linux c下简单实现服务端与多客户端同时连接

来源:互联网 发布:c语言中temp什么意思 编辑:程序博客网 时间:2024/06/16 20:54

参考文章:

http://blog.csdn.net/kangroger/article/details/41753605

http://www.cnblogs.com/xudong-bupt/archive/2013/12/29/3483059.html


       对于服务器端来说,通过bind、listen,之后accept建立新的连接。accept返回的句柄建立的连接包括四部分:源IP、源端口号、目的IP、目的端口号。这样在一个应用程序中,就算和多个客户端建立连接,在收到数据后,应用程序通过目的IP和目的端口号也能区分是哪一条连接。

服务端:

#include <sys/types.h>  #include <sys/socket.h>  #include <stdio.h>  #include <netinet/in.h>  #include <arpa/inet.h>  #include <unistd.h>  #include <string.h>  #include <stdlib.h>  #include <fcntl.h>  #include <sys/shm.h>    #define PORT  8890  #define QUEUE_SIZE   10  #define BUFFER_SIZE 1024    void str_echo(int sockfd)    {        char buffer[BUFFER_SIZE];      pid_t pid = getpid();      while(1)      {          memset(buffer,0,sizeof(buffer));          int len = recv(sockfd, buffer, sizeof(buffer),0);          if(strcmp(buffer,"exit\n")==0)          {          printf("child process: %d exited.\n",pid);              break;          }      printf("pid:%d receive:\n",pid);          fputs(buffer, stdout);          send(sockfd, buffer, len, 0);      }      close(sockfd);  }    int main(int argc, char **argv)   {      //定义IPV4的TCP连接的套接字描述符      int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);        //定义sockaddr_in      struct sockaddr_in server_sockaddr;      server_sockaddr.sin_family = AF_INET;      server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);      server_sockaddr.sin_port = htons(PORT);        //bind成功返回0,出错返回-1      if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)      {          perror("bind");          exit(1);//1为异常退出      }      printf("bind success.\n");          //listen成功返回0,出错返回-1,允许同时帧听的连接数为QUEUE_SIZE      if(listen(server_sockfd,QUEUE_SIZE) == -1)      {          perror("listen");          exit(1);      }      printf("listen success.\n");        for(;;)      {          struct sockaddr_in client_addr;          socklen_t length = sizeof(client_addr);           //进程阻塞在accept上,成功返回非负描述字,出错返回-1          int conn = accept(server_sockfd, (struct sockaddr*)&client_addr,&length);           if(conn<0)          {              perror("connect");              exit(1);          }          printf("new client accepted.\n");                    pid_t childid;          if(childid=fork()==0)//子进程          {              printf("child process: %d created.\n", getpid());              close(server_sockfd);//在子进程中关闭监听                str_echo(conn);//处理监听的连接                exit(0);          }      }        printf("closed.\n");      close(server_sockfd);      return 0;  }  
客户端:

#include <sys/types.h>  #include <sys/socket.h>  #include <stdio.h>  #include <netinet/in.h>  #include <arpa/inet.h>  #include <unistd.h>  #include <string.h>  #include <stdlib.h>  #include <fcntl.h>  #include <sys/shm.h>    #define PORT  8890  #define BUFFER_SIZE 1024    int main(int argc, char **argv)  {      if(argc!=2)        {            printf("usage: client IP \n");            exit(0);        }        //定义IPV4的TCP连接的套接字描述符      int sock_cli = socket(AF_INET,SOCK_STREAM, 0);        //定义sockaddr_in      struct sockaddr_in servaddr;      memset(&servaddr, 0, sizeof(servaddr));      servaddr.sin_family = AF_INET;      servaddr.sin_addr.s_addr = inet_addr(argv[1]);      servaddr.sin_port = htons(PORT);  //服务器端口         //连接服务器,成功返回0,错误返回-1      if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)      {          perror("connect");          exit(1);      }      printf("connect server(IP:%s).\n",argv[1]);          char sendbuf[BUFFER_SIZE];      char recvbuf[BUFFER_SIZE];      //客户端将控制台输入的信息发送给服务器端,服务器原样返回信息      while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)      {          send(sock_cli, sendbuf, strlen(sendbuf),0); ///发送          if(strcmp(sendbuf,"exit\n")==0)          {          printf("client exited.\n");              break;          }          printf("client receive:\n");          recv(sock_cli, recvbuf, sizeof(recvbuf),0); ///接收          fputs(recvbuf, stdout);            memset(sendbuf, 0, sizeof(sendbuf));          memset(recvbuf, 0, sizeof(recvbuf));      }        close(sock_cli);      return 0;  }  
server端起来后,端口情况如下:


client1和client2起来后,端口情况如下:


server运行情况如下:


client1运行情况如下:


client2运行情况如下:


0 0
原创粉丝点击