转载

socket编程与利用进程进行多并行连接

呈现一张基本的socket阻塞式模型,如下图:

socket编程与利用进程进行多并行连接

一: 对于一对一的进行C/S回射:

服务端(server.c):

 1 #include<unistd.h>  2 #include<stdio.h>  3 #include<string.h>  4 #include<stdlib.h>  5 #include<netinet/in.h>  6 #include<sys/socket.h>  7 #include<sys/types.h>  8 #include<error.h>  9  10 #define ERR_EXIT(m) / 11    do{           / 12       perror(m); / 13       exit(1);    / 14      }while(0) 15  16 int 17 main (void) 18 { 19   int sock, conn; 20   if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0) 21     ERR_EXIT ("socket"); 22   struct sockaddr_in sockaddr; 23   memset (&sockaddr, 0, sizeof (sockaddr)); 24   sockaddr.sin_family = AF_INET; 25   sockaddr.sin_port = htons (5528); 26   sockaddr.sin_addr.s_addr = htonl (INADDR_ANY); 27   if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0) 28     ERR_EXIT ("Bind"); 29   if (listen (sock, SOMAXCONN) < 0) 30     ERR_EXIT ("Listen"); 31   struct sockaddr_in client; 32   memset (&client, 0, sizeof (client)); 33   socklen_t addrlen = sizeof (client); 34   if ((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < 0) 35     ERR_EXIT ("Accept"); 36   char sed[1024], recv[1024]; 37   while (fgets (sed, sizeof (sed), stdin) != NULL || 1 == 1) 38     { 39       if (strlen (sed) > 0) 40         write (conn, sed, sizeof (sed)); 41       if (read (conn, recv, sizeof (recv)) > 0) 42         { 43           fputs (recv, stdout); 44           if (strcmp (recv, "exit") == 0) 45             break; 46           write (conn, recv, sizeof (recv)); 47         } 48       else 49         ERR_EXIT ("read..."); 50     } 51   close (conn); 52   close (sock); 53   return 0; 54 }

客户端(client.c):

 1 #include<unistd.h>  2 #include<stdio.h>  3 #include<string.h>  4 #include<error.h>  5 #include<netinet/in.h>  6 #include<stdlib.h>  7 #include<sys/socket.h>  8 #include<sys/types.h>  9                                                                                 10 #define ERR_EXIT( m ) / 11    do{          / 12       perror(m);   / 13       exit(1);       / 14     }while(0); 15                                                                                 16 int 17 main (void) 18 { 19   int socketid, conn; 20                                                                                 21   if ((socketid = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 22     ERR_EXIT ("socket"); 23  24   struct sockaddr_in server_addr; 25   memset (&server_addr, 0, sizeof (server_addr)); 26  27   server_addr.sin_family = AF_INET; 28   server_addr.sin_port = htons (5528); 29   server_addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); 30   if ((conn = 31        connect (socketid, (struct sockaddr *) &server_addr, 32                 sizeof (server_addr))) < 0) 33     ERR_EXIT ("connect"); 34   char sendbuf[1024], recivebuf[1024]; 35   while (fgets (sendbuf, sizeof (sendbuf), stdin) != NULL) 36     { 37       write (socketid, sendbuf, sizeof (sendbuf)); 38       read (socketid, recivebuf, sizeof (recivebuf)); 39       fputs (recivebuf, stdout); 40       if (strcmp (recivebuf, "exit") == 0) 41         { 42           ERR_EXIT ("exit"); 43           break; 44         } 45     } 46   close (conn); 47   close (socketid); 48   return 0; 49 }

相关的makefile文件

 1 makefile文件:  2   3 .SUFFIXES: .o.c  4 .PHONY: clean  5 .PHONY: start  6   7 CC =gcc  8 SRC =server.c  9 OBJS =$(SRC:.c =.o) 10 BIN = Server 11  12 start: 13         $(CC) -o $(BIN) $(OBJS) 14  15 .o.c: 16         $(CC) -g -Wall $@ -c $< 17 clean: 18         rm -f $(OBJS)

但是上述虽然满足了基本的socket套路,但是当我们关闭服务可执行程序时,在开启就会出现地址被占用,解决此等问题,需再加上一个setsockopt()函数,对齐进行设定。

详细可以去查询man帮助(man  setsockopt)

代码:

1  int on = 1; 2   if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) 3     { 4       ERR_EXIT ("setsockopt"); 5     } 6  7  8   if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0) 9     ERR_EXIT ("Bind");

二:  利用进程进行并行socket阻塞式连接:

客户端和makefile文件和上面一样,只是将socket的服务端,修改为调用进程来进行多并发连接即可!

服务端(server.c):

 1 #include<unistd.h>  2 #include<stdio.h>  3 #include<string.h>  4 #include<stdlib.h>  5 #include<netinet/in.h>  6 #include<sys/socket.h>  7 #include<sys/types.h>  8 #include<error.h>  9  10 #define ERR_EXIT(m) / 11    do{           / 12       perror(m); / 13       exit(1);    / 14      }while(0) 15  16  17 void 18 print (int conn){ 19  20   char sed[1024], recv[1024]; 21   while (fgets (sed, sizeof (sed), stdin) != NULL || 1 == 1) 22     { 23       if (strlen (sed) > 0) 24          write (conn, sed, sizeof (sed)); 25       if (read (conn, recv, sizeof (recv)) > 0) 26         { 27           fputs (recv, stdout); 28           if (strcmp (recv, "exit") == 0) 29                     break; 30           write (conn, recv, sizeof (recv)); 31         } 32       else 33         ERR_EXIT ("read..."); 34    } 35     close (conn); 36 } 37  38 int 39 main (void) 40 { 41   int sock, conn; 42   if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0) 43     ERR_EXIT ("socket"); 44   struct sockaddr_in sockaddr; 45   memset (&sockaddr, 0, sizeof (sockaddr)); 46   sockaddr.sin_family = AF_INET; 47   sockaddr.sin_port = htons (5528); 48   sockaddr.sin_addr.s_addr = htonl (INADDR_ANY); 49  50   int on = 1; 51   if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) 52     { 53       ERR_EXIT ("setsockopt"); 54     } 55  56  57   if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0) 58     ERR_EXIT ("Bind"); 59  60   if (listen (sock, SOMAXCONN) < 0) 61     ERR_EXIT ("Listen"); 62  63   struct sockaddr_in client; 64   memset (&client, 0, sizeof (client)); 65   socklen_t addrlen = sizeof (client); 66   pid_t pid ; 67  68   while (1) 69     { 70    if((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < 0) 71         ERR_EXIT ("Accept"); 72           pid = fork (); 73       if (pid == -1) 74            ERR_EXIT ("fork"); 75       else if (pid == 0){ 76            close (sock); 77            print (conn); 78         } 79       else 80         close (conn); 81     } 82   close (sock); 83   return 0; 84 }
正文到此结束
Loading...