利用单线程进程并发模型,实现TCP文件传输 您所在的位置:网站首页 高并发文件传输 利用单线程进程并发模型,实现TCP文件传输

利用单线程进程并发模型,实现TCP文件传输

2024-03-31 22:09| 来源: 网络整理| 查看: 265

并发服务器使用面向连接协议的步骤:

主1、创建套接字并将其绑定到所提供服务的熟知地址上。让该套接字保持为无连接的主2、将该端口设置为被动模式主3、反复调用accept以便接收来自客户的下一个连接请求,并创建新的从线程或者进程来处理响应从1、由主线程传递来的连接请求开始从2、用该连接与客户进行交互;读取请求并发回响应从3、关闭连接并退出

 

在实现过程中,要用单程进程实现并发,需要注意的是在fork()之后,分别对父子进程进行的处理。

父子进程分别拥有一个主套接字和一个从套接字

所以,在处理时,要把父进程中的从套接字close()掉,把子进程中的主套接字close()掉。

当然,这里的close不是真正关闭掉套接字,而是让主套接字在子进程中消失,从套接字在父进程中消失。

服务器端(linux)代码:

//server_linux.c #include #include #include #include #include #include #include #include #include #include #include #include #define QLEN 32 #define BUFSIZE 1024 //extern int errno; // int errexit(const char* format, ...); unsigned short portbase = 0; int passivesock(/*const char* service,*/ const char *transport, int qlen){ struct servent *pse; struct protoent *ppe; struct sockaddr_in sin; int s, type; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(8888); //if(pse = getservbyname(service, transport)) // sin.sin_port = htons(ntohs((unsigned short)pse->s_port) + portbase); //else if((sin.sin_port = htons((unsigned short)atoi(service))) == 0) // printf("can not get \" %s \" service entry \n", service); //if((ppe = getprotobyname(transport)) == 0) // printf("can not get \" %s \" protocol entry \n", transport); //if(strcmp(transport, "udp") == 0) // type = SOCK_DGRAM; //else type = SOCK_STREAM; s = socket(PF_INET, type, 0/*ppe->p_proto*/); if(s < 0){ printf("can not create socket..."); } if(bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0){ printf("can not bind the port..."); } if(type == SOCK_STREAM && listen(s, qlen) < 0) printf("can not listen the port..."); return s; } int passiveTCP(/*const char* service, */ int qlen){ return passivesock(/*service, */"tcp", QLEN); } int processFile(int ssock){ char filename[100]; char filepath[100]; //char *filepath = "C:\Users\liky\Desktop\windowToLinux.txt"; FILE *fp; char *buffer; int fileTrans; memset(filename,'\0',sizeof(filename)); memset(filepath,'\0',sizeof(filepath)); buffer = (char *)malloc(sizeof(char)*BUFSIZE); bzero(buffer,BUFSIZE); int lenfilepath = recv(ssock,filepath,100,0); printf("filepath :%s\n",filepath); if(lenfilepath < 0){ printf("recv error!\n"); return 1; }else{ int i=0,k=0; for(i=strlen(filepath);i>=0;i--) { if(filepath[i]!='/'){ k++; }else break; } strcpy(filename,filepath+(strlen(filepath)-k)+1); } printf("filename :%s\n",filename); fp = fopen(filename,"w"); if(fp!=NULL){ while(fileTrans = recv(ssock,buffer,BUFSIZE,0)){ if(fileTrans= 0) ; } int main(int argc, char *argv[]){ char* service; struct sockaddr_in fsin; unsigned int alen; int msock; int ssock; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: printf("usage: TCP port error..."); } msock = passiveTCP(/*service, */ QLEN); // signal (void)signal(SIGCHLD, reaper); //子进程结束时发出的信号 while(1){ alen = sizeof(fsin); sleep(2); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if(ssock < 0){ printf("accpet error...\n"); continue; }else{ printf("accpet successful\n"); } switch(fork()){ case 0: (void) close(msock); printf("a new process is created\n"); //处理函数 exit(processFile(ssock)); case 1: (void) close(ssock); break; case -1: printf("fork error..."); } } }

客户端(linux)代码:(此处写的比较随意)

//client_linux.c #include #include #include #include #include #include #include #include //for malloc #define BUFFER_SIZE 1024 int main() { int sockcd; struct sockaddr_in server; char filepath[100];//file to translate FILE *fp; int lenpath; //filepath length char *buffer; int fileTrans; buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE); bzero(buffer,BUFFER_SIZE); //memset(buffer,0,sizeof(buffer)); if((sockcd = socket(AF_INET,SOCK_STREAM,0))


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有