转自csdn博客:http://blog.youkuaiyun.com/rao_warrior/article/details/8188687
运行环境:centos 6.3
说明 :UNIX 网络编程测试代码
将客户端、服务端、以及广播消息的服务端都集成一段代码里面,个人感觉还不错呵呵呵
里面的注释不多,但是应该不难读懂的,还算比较容易
可以把一面代码直接贴下来,用gcc 编译跑一下,会发现在效果还不错
- #include <stdio.h>
- #include <sys/types.h> /* See NOTES */
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <string.h>
- #include <errno.h>
- #include <stdlib.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- typedef struct sockaddr_in sockaddr_in;
- typedef struct sockaddr sockaddr;
- int main(int argc, char ** argv) {
- sockaddr_in srv, cli;
- int fd, sfd, is_server;
- if (argc < 3) {
- printf(
- "please put the arguments ,like ./a.out addr_ip addr_port [server/client/broad]");
- return -1;
- }
- if (argc >= 4) {
- if (strcmp("server", argv[3]) == 0) {
- is_server = 1;
- printf("i am server \n");
- } else if (strcmp("client", argv[3]) == 0) {
- is_server = 0;
- printf("i am client \n");
- } else if(strcmp("broad",argv[3]) == 0){
- is_server = 2;
- printf("i want broad msg ,broad ip:X.X.X.255 \n");
- } else {
- printf("arguments error\n");
- return -1;
- }
- } else {//default
- is_server = -1 ;
- printf("i could recv and send msg ,muti process\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("server socket error");
- }
- if(is_server != -1){
- fd = 1-is_server ;
- }else{
- fd = fork();
- if (fd < 0) {
- perror("fork error");
- return -1;
- }
- }
- if (0 == fd) { //service is_server == 1
- char recvbuf[1024];
- char ip[50];
- socklen_t len;
- int rnu = 0;
- srv.sin_addr.s_addr = INADDR_ANY ;
- int bfd;
- if ((bfd = bind(sfd, (sockaddr*) &srv, sizeof(sockaddr))) < 0) {
- perror("bind error");
- }
- while (1) {
- memset(recvbuf, 0, sizeof(recvbuf));
- len = sizeof(sockaddr);
- if((rnu = recvfrom(sfd, recvbuf, sizeof(recvbuf), 0, (sockaddr*) &cli,&len))<0) {
- printf("recvfrom error");
- } 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("sendto error");
- }
- //printf("send:%s\n", inet_ntop(AF_INET, &srv.sin_addr, ip, sizeof(ip)));
- sleep(2);
- }
- }
- close(sfd);
- }else if(-1 == fd){//broadcast
- char recvbuf[1024];
- char ip[50];
- socklen_t len;
- int rnu = 0;
- srv.sin_addr.s_addr = INADDR_ANY ;
- int bfd;
- if ((bfd = bind(sfd, (sockaddr*) &srv, sizeof(sockaddr))) < 0) {
- perror("bind error");
- }
- while (1) {
- memset(recvbuf, 0, sizeof(recvbuf));
- len = sizeof(sockaddr);
- int on_broadcast = 1;
- int rs = 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_pton error:");
- }
- strcpy(recvbuf, "this is broad\n");
- if (sendto(sfd, recvbuf, strlen(recvbuf), 0, (sockaddr*) &srv, len)
- < 0) {
- perror("sendto error");
- }
- printf("send:%s\n",
- inet_ntop(AF_INET, &srv.sin_addr, ip, sizeof(ip)));
- sleep(2);
- }
- close(sfd);
- }else {
- char sendbuf[1024], *p = sendbuf;
- ssize_t bs;
- char ip[50];
- socklen_t len = 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> /* See NOTES */
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- #define MAXLINE 1024
- typedef struct sockaddr_in sockaddr_in ;
- typedef struct sockaddr sockaddr ;
- #define MAX_FD_CONN 1000
- int main(int argc ,char ** argv){
- int sock ,con;
- int nready ,nfd;
- sockaddr_in srv,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);
- char buf[1024];
- fd_set rset,allfd ;
- int conns[ MAX_FD_CONN ] ,i ,nr;
- socklen_t len ;
- for(i =0 ;i<MAX_FD_CONN;i++)
- conns[i] = -1;
- FD_ZERO(&allfd);
- FD_SET(sock,&allfd );
- nfd = sock+1;
- <span style="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++){ /*if maxsize >MAX_FD_CONN, throw and close the connect */
- 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);
- return 0;
- }
在此我也把客户端连接的测试的代码也贴出来,分享一下,也防止以后忘了呵呵呵
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h> /* See NOTES */
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- #define MAXLINE 1024
- typedef struct sockaddr_in sockaddr_in ;
- typedef struct sockaddr sockaddr ;
- int main(int argc ,char ** argv){
- int sock ;
- int sel ,nfd;
- sockaddr_in srv,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);
- char buf[1024];
- fd_set rset ,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;
- int rn ;
- bzero(buf,sizeof(buf));
- while((sel = select(nfd, &rset,&wset,NULL,NULL ))){
- printf("select begin\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)){
- int wn = write(sock,buf,rn );
- bzero(buf,sizeof(buf));
- FD_CLR(sock,&wset );
- }
- FD_SET(STDIN_FILENO ,&rset );
- FD_SET(sock ,&rset );
- }
- close(sock);
- return 0;
- }
- 下面给出一个性能测试实例
- 下面使用200个线程,而且是并发执行哦!每个线程写入1000*1000*10B的数据
- 测试成功
- <pre name="code" class="cpp">typedef struct sockaddr_in sockaddr_in;
- typedef struct sockaddr sockaddr ;
- void *thread_fun(void*arg ){
- struct sockaddr_in ser,cli ;
- int fd ,bs,fdc,i;
- socklen_t len;
- char buf[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("socket error\n");
- //int nZero=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("write error:");
- }
- // printf("%d\n",i);
- close(fd);
- // sleep(1);
- pthread_exit((void*)arg);
- }
- const int num_thre = 200;
- int main(){
- int i =0;
- int res;
- pthread_t send_msg[num_thre];
- for(i=0;i<num_thre;i++){
- if(pthread_create(send_msg+i,NULL,thread_fun,i)!=0)
- printf("pthread create error\n");
- }
- for(i=0;i<num_thre;i++){
- pthread_join(send_msg[i],(void**)(&res));
- printf("%dover\n",res);
- }
- printf("over \n");
- return 0;
- }
- </pre><br>
- <br>
- <pre></pre>
- <p></p>
- <pre></pre>