📄 tcpserver.c
字号:
/* A toy server for ppc to test the transfer rate of block data in tcp mode. * Create by cuiwei * 2007-06-3*///#define fb_test//#define hostname#ifdef fb_test#include "fb.h"#endif#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <fcntl.h>#include <signal.h>#include <poll.h> /* for convenience */#include <sys/select.h> /* for convenience */#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/fcntl.h>#include <sys/ioctl.h>#include <sys/mman.h>//no need//#include <linux/net.h>//而且包含 #include <sys/wait.h>//#include <sys/wait.h>#include <net/if.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <pthread.h>#define PORT 5000#define QUEUE_SIZE 20#define PACKET_SIZE 1024 #define SA struct sockaddr//相当于inet_ntoa ,但没有重入问题#define NIPQUAD(addr) \ ((unsigned char *)&addr)[0], \ ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[2], \ ((unsigned char *)&addr)[3] unsigned int flag;static char source[16];//参数结构struct p_t{ unsigned int nsecond; unsigned int npacket;};void sig_int(int signo){ exit(0);}void killer(){ char sptr[]="Connection shutdown!"; printf("%s\n",sptr);#ifdef fb_test display_char(3, 3, sptr , strlen(sptr) , 1, 15, 0);#endif flag = 1;}int read_and_send(int new_fd){ struct p_t send_para;//参数 int fd_send;//发送文件描述符 int second,packet_size = 0;//计时 register int k,i; unsigned int sum,sumk; char str[PACKET_SIZE];#if 1 //open file if((fd_send = open(source,O_RDONLY))<0){ perror("原文件打开错误!\n"); exit(1); } printf("正在传送文件,稍候!\n"); //读取传输参数 if(read(new_fd,&send_para,sizeof(send_para))==-1){ printf("Read time(in second) failed!\n"); exit(6); } second=ntohl(send_para.nsecond); packet_size=ntohl(send_para.npacket); printf("Transfer time=%d(s) packet_size:%d\n",second,packet_size); ///////////////////////////////////////////////////////////////// signal(SIGALRM,killer); alarm(second); sum = sumk= 0; /*发送文件名*/ write(new_fd,source,sizeof(source)); // printf("Send file name wrong!\n");//校验 printf("send file name is %s\n",source); /*每次接受客户机连接,应将用于读的源文件指针移到文件头*/ lseek(fd_send,0L,SEEK_SET); while((k = read(fd_send,str,( packet_size>sizeof(str) ? sizeof(str) : packet_size ) ))>0) { write(new_fd ,str ,k); sum += k; //printf("%d\t",sum); if(flag){ printf("文件传输超时,用时%d(s)\n",second); close(new_fd); close(fd_send); exit(7); } if(!(sum%1000)){ printf("sum = %dkbyte\t", sum/1000); } } second -= alarm(0); printf("\n"); printf("文件传输完毕!!!\n"); close(new_fd); close(fd_send); //统计数据 printf("Current Package size: %d\n",sizeof(str)); printf("The total size :%d bytes!\n",sum); printf("文件发送用时%d(s)\n",second); printf("Transfer Speed=%d Mbps!\n",sum*8/( ( second == 0 ? 1:second ) *0x100000)); printf("\n"); return 0;#endif}void *doit(void *arg){ printf("pid=%d,pthreadid=%d\n",getpid(),pthread_self()); pthread_detach(pthread_self()); read_and_send((int) arg); close((int) arg); return(NULL);}int main(int argc,char* argv[]){ struct sockaddr_in srvaddr,*sin;//server addr struct sockaddr_in cliaddr;//client addr struct ifreq ifr;//Interface request structure struct hostent *hp; unsigned int port;//ip2; int sockfd; // int new_fd; int i; char c,*ip; #if 0 struct p_t send_para; int second,packet_size;//计时 register int sockfd,new_fd,k,i; int fd_send;//发送文件描述符 unsigned int sum,sumk; char str[PACKET_SIZE],source[16],c,*ip; #endif pthread_t tid; //结构长度 socklen_t clilen;//int sin_size;//length flag = 0; ip = (char *)malloc(30); //memset(&ifr, 0x00, sizeof(ifr)); bzero (&ifr,sizeof(ifr)); bzero (&srvaddr,sizeof(srvaddr)); //系统指令调用 system("clear"); port = PORT; if(argc == 2 ) port = (port>1000 ? atoi(argv[1]) : port) ; #ifdef fb_test initialize_display(); display_char(3, 3, "Initialize end!" , 16 , 0, 15, 0); display_char(4, 0, "请输入文件名:", 13, 0 ,15,0 ); display_char(4, 13," ",18, 1 ,15,0);#endif printf("请输入路径及文件名:"); for (i=0; ( c = getchar()) != '\n' ;i++){ source[i] = c;#ifdef fb_test display_char(4, 13+i,&source[i],1, 1 ,15,0); cursor_pos(4, 14+i);#endif } source[i] = 0; //得到主机地址 hp = gethostbyname("server"); //192.168.1.234 server.localdomain server if(hp==NULL){ perror("返回主机地址信息错!!!\n"); exit(2); } //建立插座 /* if((sockfd=socket(PF_INET,SOCK_STREAM,0))== -1){*/ //Socket系统调用 调用建立tcp协议通道 if((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1){ perror("Create err\n"); exit(3); } srvaddr.sin_family = AF_INET; srvaddr.sin_port=htons(port);//需要转化 //若 srvaddr.sin_port = 0; /* 系统随机选择一个未被使用的端口号 */ //srvaddr.sin_addr.s_addr=htonl(INADDR_ANY);//0x00000000任意地址 //scr //dest bcopy(hp->h_addr,&(srvaddr.sin_addr),hp->h_length); // strcpy(ifr.ifr_name, "eth0"); //得到本机ip的另一种方法 #if 1#ifndef hostname //好 ioctl(sockfd,SIOCGIFADDR,&ifr);/* get PA address */ sin = (struct sockaddr_in *) &(ifr.ifr_addr); ip = (char *)inet_ntoa(sin->sin_addr);#else //下策 //&srvaddr = (struct sockaddr_in *)&(ifr.ifr_addr); //错误 bcopy(&(ifr.ifr_addr),&(srvaddr),sizeof(srvaddr)); // ip = (char *)inet_ntoa(srvaddr.sin_addr);#endif #endif //得到本机netmask //ioctl(sockfd,SIOCGIFNETMASK,&ifr);/* get network PA mask */ //sin = (struct sockaddr_in *) &(ifr.ifr_netmask); //ip = (char *)inet_ntoa(sin->sin_addr); //子网掩码可以计算 但如何读取??? //ip = (char *)inet_ntoa(ifr.ifr_netmask); //wrong //ip2 = sin->sin_addr.s_addr; //ip = NIPQUAD(ip2); /*bind*/ //if(bind(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr))==-1){ if(bind(sockfd,(SA *)&srvaddr,sizeof(/*srvaddr*/SA))<0){ perror("不能将服务器地址捆绑到SOCKET号上!!!\n"); close(sockfd); exit(4); } //print server addr printf("Host name : %s\n", hp->h_name); //printf("Serveraddr:%s \t NetMask:%s \n", inet_ntoa(srvaddr.sin_addr),ip); printf("Serveraddr:%s \n", inet_ntoa(srvaddr.sin_addr)); //监听 if(listen(sockfd, QUEUE_SIZE) == -1){ perror("listen error"); exit(5); } signal(SIGINT, sig_int); //等待连接 for(;;){ //sin_size = sizeof(struct sockaddr_in); clilen = sizeof(cliaddr); //连接 new_fd = accept(sockfd,(SA *) &cliaddr,&clilen); printf("Server:Got connection from %s \n",inet_ntoa(cliaddr.sin_addr)); //创建线程 pthread_create(&tid, NULL, &doit, (void *) new_fd);/* //子进程代码段 if (!fork()) { while (send(new_fd, "Hello, you are connected!\n", 26, 0) == -1) perror("send出错!"); close(new_fd); exit(0); }*/ }//for}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -