linux 下UDP通信(附加测试代码) – GOD

运行环境:centos 6.3

说明 :UNIX 网络编程测试代码

将客户端、服务端、以及广播消息的服务端都集成一段代码里面,个人感觉还不错呵呵呵

里面的注释不多,但是应该不难读懂的,还算比较容易

可以把一面代码直接贴下来,用gcc 编译跑一下,会发现在效果还不错

    #include<stdio.h>#include<sys/types.h>/*SeeNOTES*/#include<sys/socket.h>#include<netinet/in.h>#include<string.h>#include<errno.h>#include<stdlib.h>#include<arpa/inet.h>#include<unistd.h>typedefstructsockaddr_insockaddr_in;typedefstructsockaddrsockaddr;intmain(intargc,char**argv){sockaddr_insrv,cli;intfd,sfd,is_server;if(argc<3){printf("pleaseputthearguments,like./a.outaddr_ipaddr_port[server/client/broad]");return-1;}if(argc>=4){if(strcmp("server",argv[3])==0){is_server=1;printf("iamserver\n");}elseif(strcmp("client",argv[3])==0){is_server=0;printf("iamclient\n");}elseif(strcmp("broad",argv[3])==0){is_server=2;printf("iwantbroadmsg,broadip:X.X.X.255\n");}else{printf("argumentserror\n");return-1;}}else{//defaultis_server=-1;printf("icouldrecvandsendmsg,mutiprocess\n");}memset(&srv,0,sizeof(srv));srv.sin_port=htons(atoi(argv[2]));srv.sin_family=AF_INET;if((sfd=socket(AF_INET,SOCK_DGRAM,0))<0){perror("serversocketerror");}if(is_server!=-1){fd=1-is_server;}else{fd=fork();if(fd<0){perror("forkerror");return-1;}}if(0==fd){//serviceis_server==1charrecvbuf[1024];charip[50];socklen_tlen;intrnu=0;srv.sin_addr.s_addr=INADDR_ANY;intbfd;if((bfd=bind(sfd,(sockaddr*)&srv,sizeof(sockaddr)))<0){perror("binderror");}while(1){memset(recvbuf,0,sizeof(recvbuf));len=sizeof(sockaddr);if((rnu=recvfrom(sfd,recvbuf,sizeof(recvbuf),0,(sockaddr*)&cli,&len))<0){printf("recvfromerror");}else{printf("from:%s,recv:%s",inet_ntop(AF_INET,&cli.sin_addr,ip,sizeof(ip)),recvbuf);if(is_server!=-1&&sendto(sfd,recvbuf,strlen(recvbuf),0,(sockaddr*)&srv,len)<0){perror("sendtoerror");}//printf("send:%s\n",inet_ntop(AF_INET,&srv.sin_addr,ip,sizeof(ip)));sleep(2);}}close(sfd);}elseif(-1==fd){//broadcastcharrecvbuf[1024];charip[50];socklen_tlen;intrnu=0;srv.sin_addr.s_addr=INADDR_ANY;intbfd;if((bfd=bind(sfd,(sockaddr*)&srv,sizeof(sockaddr)))<0){perror("binderror");}while(1){memset(recvbuf,0,sizeof(recvbuf));len=sizeof(sockaddr);inton_broadcast=1;intrs=setsockopt(sfd,SOL_SOCKET,SO_BROADCAST,&on_broadcast,sizeof(on_broadcast));if((rs=inet_pton(AF_INET,"10.33.28.255",&srv.sin_addr))<=0){perror("inet_ptonerror:");}strcpy(recvbuf,"thisisbroad\n");if(sendto(sfd,recvbuf,strlen(recvbuf),0,(sockaddr*)&srv,len)<0){perror("sendtoerror");}printf("send:%s\n",inet_ntop(AF_INET,&srv.sin_addr,ip,sizeof(ip)));sleep(2);}close(sfd);}else{charsendbuf[1024],*p=sendbuf;ssize_tbs;charip[50];socklen_tlen=sizeof(sockaddr);inet_aton(argv[1],&srv.sin_addr);while(1){memset(sendbuf,0,sizeof(sendbuf));bs=sizeof(sendbuf);bs=getline(&p,&bs,stdin);bs=sendto(sfd,sendbuf,bs,0,(sockaddr*)&srv,len);printf("sendto:%s",sendbuf);if(is_server!=-1&&(bs=recvfrom(sfd,sendbuf,sizeof(sendbuf),0,(sockaddr*)&cli,&len))>0){printf("from:%s,recv:%s",inet_ntop(AF_INET,&cli.sin_addr,ip,sizeof(ip)),sendbuf);}}close(sfd);}}

下面是一个很不错的select的例子,避免了调用fork而产生的新进程的开销:

下面是server 代码:

    #include<stdio.h>#include<stdlib.h>#include<sys/types.h>/*SeeNOTES*/#include<sys/socket.h>#include<netinet/in.h>#include<string.h>#include<errno.h>#include<unistd.h>#include<arpa/inet.h>#defineMAXLINE1024typedefstructsockaddr_insockaddr_in;typedefstructsockaddrsockaddr;#defineMAX_FD_CONN1000intmain(intargc,char**argv){intsock,con;intnready,nfd;sockaddr_insrv,cli;if((sock=socket(AF_INET,SOCK_STREAM,0))==-1){perror("socket");return-1;}bzero(&srv,0);srv.sin_family=AF_INET;srv.sin_port=htons(8070);srv.sin_addr.s_addr=htonl(INADDR_ANY);if((bind(sock,(sockaddr*)&srv,sizeof(sockaddr)))<0){perror("bind");return-1;}listen(sock,10);charbuf[1024];fd_setrset,allfd;intconns[MAX_FD_CONN],i,nr;socklen_tlen;for(i=0;i<MAX_FD_CONN;i++)conns[i]=-1;FD_ZERO(&allfd);FD_SET(sock,&allfd);nfd=sock+1;<spanstyle="white-space:pre"></span>FD_SET(sock,&allfd);while(1){rset=allfd;//这个是相当的关键一行哦,UNP(1)上说,select对参数是有修改的,一定要注意保存啊,不然会出现意想不到的问题nready=select(nfd,&rset,NULL,NULL,NULL);if(FD_ISSET(sock,&rset)){len=sizeof(sockaddr);if((con=accept(sock,(sockaddr*)&cli,&len))==-1){perror("accept");continue;}for(i=0;i<MAX_FD_CONN;i++){/*ifmaxsize>MAX_FD_CONN,throwandclosetheconnect*/if(conns[i]==-1){conns[i]=con;FD_SET(con,&allfd);break;}}if(MAX_FD_CONN==i)close(con);if(nfd<=con)nfd=con+1;if(–nready<=0){continue;}}for(i=0;i<MAX_FD_CONN;i++){if(conns[i]==-1)continue;if(FD_ISSET(conns[i],&rset)){bzero(buf,sizeof(buf));if((nr=read(conns[i],buf,sizeof(buf)))<=0){close(conns[i]);FD_CLR(conns[i],&allfd);continue;}else{printf("read:%s\n",buf);write(conns[i],buf,nr);}}if(–nready<=0)break;}}close(sock);return0;}

在此我也把客户端连接的测试的代码也贴出来,分享一下,也防止以后忘了呵呵呵

    #include<stdio.h>#include<stdlib.h>#include<sys/types.h>/*SeeNOTES*/#include<sys/socket.h>#include<netinet/in.h>#include<string.h>#include<errno.h>#include<unistd.h>#include<arpa/inet.h>#defineMAXLINE1024typedefstructsockaddr_insockaddr_in;typedefstructsockaddrsockaddr;intmain(intargc,char**argv){intsock;intsel,nfd;sockaddr_insrv,cli;if((sock=socket(AF_INET,SOCK_STREAM,0))==-1){perror("socket");return-1;}bzero(&srv,0);srv.sin_family=AF_INET;srv.sin_port=htons(atoi(argv[2]));inet_pton(AF_INET,argv[1],&srv.sin_addr);charbuf[1024];fd_setrset,wset;FD_ZERO(&rset);FD_ZERO(&wset);FD_SET(STDIN_FILENO,&rset);FD_SET(sock,&rset);if(connect(sock,(sockaddr*)&srv,sizeof(sockaddr))<0){perror("connect:");return-1;}perror("con");nfd=sock+1;intrn;bzero(buf,sizeof(buf));while((sel=select(nfd,&rset,&wset,NULL,NULL))){printf("selectbegin\n");if(FD_ISSET(sock,&rset)){bzero(buf,sizeof(buf));read(sock,buf,sizeof(buf));printf("read:%s\n",buf);}if(FD_ISSET(STDIN_FILENO,&rset)){bzero(buf,sizeof(buf));rn=read(STDIN_FILENO,buf,sizeof(buf));if(rn>0)FD_SET(sock,&wset);}if(FD_ISSET(sock,&wset)){intwn=write(sock,buf,rn);bzero(buf,sizeof(buf));FD_CLR(sock,&wset);}FD_SET(STDIN_FILENO,&rset);FD_SET(sock,&rset);}close(sock);return0;}
    下面给出一个性能测试实例
      下面使用200个线程,而且是并发执行哦!每个线程写入1000*1000*10B的数据
      测试成功
      <prename="code"class="cpp">typedefstructsockaddr_insockaddr_in;typedefstructsockaddrsockaddr;void*thread_fun(void*arg){structsockaddr_inser,cli;intfd,bs,fdc,i;socklen_tlen;charbuf[1024];bzero(&ser,sizeof(sockaddr));ser.sin_port=8080;inet_pton(AF_INET,"10.33.28.230",(void*)&ser.sin_addr);ser.sin_family=AF_INET;fd=socket(AF_INET,SOCK_STREAM,0);if(fd<0)perror("socketerror\n");//intnZero=0;//setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(char*)&nZero,sizeof(nZero));printf("threadID:%d\n",(int)arg);sleep(2);connect(fd,(sockaddr*)&ser,sizeof(sockaddr));for(i=0;i<1000*1000;i++){bzero(buf,sizeof(buf));sprintf(buf,"%10d",(int)arg);if(write(fd,buf,strlen(buf))<=0)perror("writeerror:");}//printf("%d\n",i);close(fd);//sleep(1);pthread_exit((void*)arg);}constintnum_thre=200;intmain(){inti=0;intres;pthread_tsend_msg[num_thre];for(i=0;i<num_thre;i++){if(pthread_create(send_msg+i,NULL,thread_fun,i)!=0)printf("pthreadcreateerror\n");}for(i=0;i<num_thre;i++){pthread_join(send_msg[i],(void**)(&res));printf("%dover\n",res);}printf("over\n");return0;}</pre><br><br><pre></pre><p></p><pre></pre>

    并且为之实践了关怀和付出的善举。对于我性情中的易感和怨薄,

    linux  下UDP通信(附加测试代码) – GOD

    相关文章:

    你感兴趣的文章:

    标签云: