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

jopen 9年前

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

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

服务端(server.c):

#include<unistd.h>  #include<stdio.h>  #include<string.h>  #include<stdlib.h>  #include<netinet/in.h>  #include<sys/socket.h>  #include<sys/types.h>  #include<error.h>    #define ERR_EXIT(m) \     do{           \        perror(m); \        exit(1);    \       }while(0)    int  main (void)  {    int sock, conn;    if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)      ERR_EXIT ("socket");    struct sockaddr_in sockaddr;    memset (&sockaddr, 0, sizeof (sockaddr));    sockaddr.sin_family = AF_INET;    sockaddr.sin_port = htons (5528);    sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);    if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)      ERR_EXIT ("Bind");    if (listen (sock, SOMAXCONN) < 0)      ERR_EXIT ("Listen");    struct sockaddr_in client;    memset (&client, 0, sizeof (client));    socklen_t addrlen = sizeof (client);    if ((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < 0)      ERR_EXIT ("Accept");    char sed[1024], recv[1024];    while (fgets (sed, sizeof (sed), stdin) != NULL || 1 == 1)      {        if (strlen (sed) > 0)          write (conn, sed, sizeof (sed));        if (read (conn, recv, sizeof (recv)) > 0)          {            fputs (recv, stdout);            if (strcmp (recv, "exit") == 0)              break;            write (conn, recv, sizeof (recv));          }        else          ERR_EXIT ("read...");      }    close (conn);    close (sock);    return 0;  }

客户端(client.c):
#include<unistd.h>  #include<stdio.h>  #include<string.h>  #include<error.h>  #include<netinet/in.h>  #include<stdlib.h>  #include<sys/socket.h>  #include<sys/types.h>                                                                                   #define ERR_EXIT( m ) \     do{          \        perror(m);   \        exit(1);       \      }while(0);                                                                                   int  main (void)  {    int socketid, conn;                                                                                     if ((socketid = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)      ERR_EXIT ("socket");      struct sockaddr_in server_addr;    memset (&server_addr, 0, sizeof (server_addr));      server_addr.sin_family = AF_INET;    server_addr.sin_port = htons (5528);    server_addr.sin_addr.s_addr = inet_addr ("127.0.0.1");    if ((conn =         connect (socketid, (struct sockaddr *) &server_addr,                  sizeof (server_addr))) < 0)      ERR_EXIT ("connect");    char sendbuf[1024], recivebuf[1024];    while (fgets (sendbuf, sizeof (sendbuf), stdin) != NULL)      {        write (socketid, sendbuf, sizeof (sendbuf));        read (socketid, recivebuf, sizeof (recivebuf));        fputs (recivebuf, stdout);        if (strcmp (recivebuf, "exit") == 0)          {            ERR_EXIT ("exit");            break;          }      }    close (conn);    close (socketid);    return 0;  }

  相关的makefile文件

makefile文件:    .SUFFIXES: .o.c  .PHONY: clean  .PHONY: start    CC =gcc  SRC =server.c  OBJS =$(SRC:.c =.o)  BIN = Server    start:          $(CC) -o $(BIN) $(OBJS)    .o.c:          $(CC) -g -Wall $@ -c $<  clean:          rm -f $(OBJS)

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

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

   代码:
        

int on = 1;    if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)      {        ERR_EXIT ("setsockopt");      }        if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)      ERR_EXIT ("Bind");

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

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

 

      服务端(server.c):

#include<unistd.h>  #include<stdio.h>  #include<string.h>  #include<stdlib.h>  #include<netinet/in.h>  #include<sys/socket.h>  #include<sys/types.h>  #include<error.h>    #define ERR_EXIT(m) \     do{           \        perror(m); \        exit(1);    \       }while(0)      void  print (int conn){      char sed[1024], recv[1024];    while (fgets (sed, sizeof (sed), stdin) != NULL || 1 == 1)      {        if (strlen (sed) > 0)           write (conn, sed, sizeof (sed));        if (read (conn, recv, sizeof (recv)) > 0)          {            fputs (recv, stdout);            if (strcmp (recv, "exit") == 0)                      break;            write (conn, recv, sizeof (recv));          }        else          ERR_EXIT ("read...");     }      close (conn);  }    int  main (void)  {    int sock, conn;    if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)      ERR_EXIT ("socket");    struct sockaddr_in sockaddr;    memset (&sockaddr, 0, sizeof (sockaddr));    sockaddr.sin_family = AF_INET;    sockaddr.sin_port = htons (5528);    sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);      int on = 1;    if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)      {        ERR_EXIT ("setsockopt");      }        if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)      ERR_EXIT ("Bind");      if (listen (sock, SOMAXCONN) < 0)      ERR_EXIT ("Listen");      struct sockaddr_in client;    memset (&client, 0, sizeof (client));    socklen_t addrlen = sizeof (client);    pid_t pid ;      while (1)      {     if((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < 0)          ERR_EXIT ("Accept");            pid = fork ();        if (pid == -1)             ERR_EXIT ("fork");        else if (pid == 0){             close (sock);             print (conn);          }        else          close (conn);      }    close (sock);    return 0;  }

编程是一种快乐,享受代码带给我的乐趣!!!
来自:http://www.cnblogs.com/gongxijun/p/4592864.html