Linux C 套接字socket select

server端:

                  int sockfd;        sockfd = socket(AF_INET, SOCK_STREAM, 0);  //创建套接字  SOCK_STREAM : TCP

                 int opt = 1;        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  //设置套接字 option

                struct sockaddr_in serverAddr;         serverAddr.sin_family = AF_INET;  //AF_INET : IPv4协议族

                                                                                 serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);  //任意本机地址

                                                                                serverAddr.sin_port = htons(8888);  //端口

                 int len = sizeof(struct sockaddr);

                 bind(socfd, (struct sockaddr *)&serverAddr, len);  //绑定套接口

                  listen(sockfd, 10);

                  fd_set readfds, currentfds;              FD_ZERO(&readfds);      FD_SET(sockfd, &readfds);

                  int maxfd;     maxfd = sockfd;

                  select(maxfd + 1, &currentfds, NULL, NULL, NULL);

                  FD_ISSET(i, &currentfds);

                   acceptfd = accept(sockfd, (struct sockaddr *)clientAddr, &len);

                   maxfd = maxfd > acceptfd ? maxfd : acceptfd;

                   FD_SET(acceptfd, &readfds);

                   int rcvLen;       rcvLen = recv(i, readbuf, sizeof(readbuf));

                   send(i, readbuf, strlen(readbuf), 0);


client端:

                int sockfd;          sockfd = socket(AF_INET, SOCK_STREAM, 0);

                strucr sockaddr_in serverAddr;             serverAddr.sin_family =                  .sin_addr.s_addr =                .sin_port = 

                connect(sockfd, (struct sockaddr *)serverAddr, sizeof(serverAddr));

                fgets(sendbuf, 128, stdin);

               send(sockfd, sendbuf, 128, 0);

                int rcvLen;         rcvLen = recv(sockfd, rcvbuf, 128, 0);


代码(server):

  1 #include <stdio.h>
  2 #include <netinet/in.h>
  3 #include <string.h>
  4 
  5 #include <sys/socket.h>
  6 #include <sys/types.h>
  7 
  8 int main()
  9 {
 10         int sockfd;
 11         struct sockaddr_in serverAddr, clientAddr;
 12         socklen_t len = sizeof(struct sockaddr);
 13         sockfd = socket(AF_INET, SOCK_STREAM, 0);
 14         int opt = 1;
 15 
 16         fd_set readfds, currentfds;
 17         int maxfd, i, acceptfd;
 18         int rcvLen;
 19 
 20         char readbuf[128];
 21 
 22         setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  //创建套接字
 23 
 24         bzero(&serverAddr, sizeof(serverAddr));
 25         serverAddr.sin_family = AF_INET;
 26         serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
 27         serverAddr.sin_port = htons(8888);
 28 
 29         bind(sockfd, (struct sockaddr *)&serverAddr, len);  //绑定套接口
 30 
 31         listen(sockfd, 10);     //监听
 32 
 33         FD_ZERO(&readfds);
 34         FD_SET(sockfd, &readfds);
 35 
 36         maxfd = sockfd;
 37 
 38         while(1)
 39         {
 40                 currentfds = readfds;
 41                 select(maxfd + 1, ¤tfds, NULL, NULL, NULL);
 42                 for(i = 0; i < maxfd + 1; i++)  //扫描所有套接字
 43                 {
 44                         if(FD_ISSET(i, ¤tfds)) //找到相关文件描述符 
 45                         {
 46                                 if(i == sockfd) //判断是否为服务器套接字,是 则表示客户端请求连接
 47                                 {
 48                                         acceptfd = accept(sockfd, (struct sockaddr *)&clientAddr, &len);//接受连接请求
 49                                         printf("accept fd = %d\n", acceptfd);
 50                                         printf("IP = 0x%X\n",ntohl(clientAddr.sin_addr.s_addr));
 51                                         //FD_CLR(i, ¤tfds);
 52                                         maxfd = maxfd > acceptfd ? maxfd: acceptfd;
 53                                         FD_SET(acceptfd, &readfds); //将客户端socket加入到集合中
 54                                 }
 55 
 56                                 else //客户端socket中有数据请求
 57                                 {
 58                                         printf("read socket = %d\n", i);
 59                                         bzero(readbuf, sizeof(readbuf));
 60                                         rcvLen = recv(i, readbuf, sizeof(readbuf), 0);  //读
 61                                         if(rcvLen < 0)
 62                                         {
 63                                                 perror("server receive error.\n");
 64                                                 return -1;
 65                                         }
 66                                         if(rcvLen == 0)
 67                                         {
 68                                                 FD_CLR(i, &readfds);
 69                                                 close(i);
 70                                                 continue;
 71                                         }
 72                                         printf("receive [%d bytes]: %s\n", rcvLen, readbuf);
 73                                         send(i, readbuf, strlen(readbuf), 0);
 74                                 }
 75                         }
 76                 }
 77 
 78         }
 79 
 80         return 0;
 81 }

代码(client):

  1 #include <stdio.h>
  2 #include <netinet/in.h>
  3 #include <string.h>
  4 //#include <sys/socket.h>
  5 
  6 int main(int argc, char *argv[])
  7 {
  8         int sockfd;
  9 
 10         //short int sin_family; 协议族,在socket编程中 只能是AF_INET
 11         //unsigned short int sin_port;  端口号,使用网络字节顺序
 12         //struct in_addr sin_addr; 含unsigned long s_addr; 存储IP地址
 13         //unsigned char sin_zero[8];
 14         struct sockaddr_in servAddr;    //库 <netinet/in.h>
 15 
 16         int rcvLen;
 17         char sendbuf[128];
 18         char rcvbuf[128];
 19 
 20         //int socket(int domain, int type, int protocol)
 21         //参数domain;设置网络通信的域,即选择通信协议族。AF_INET为IPv4
 22         //参数type:设置套接字通信的类型,主要有SOCK_STREAM(流式套接字,TCP连接)、SOCK_DGRAM(数据包套接字,UDP连接)
 23         //参数protocol:制定type协议类型中的某个特定类型。通常某协议中只有一种特定类型,即protocol参数仅能设为0
 24         sockfd = socket(AF_INET, SOCK_STREAM, 0);       //创建 套接字
 25         printf("client socket create success. sockfd = %d\n", sockfd);
 26 
 27         bzero(&servAddr, sizeof(servAddr));     //初始化 servAddr变量
 28         servAddr.sin_family = AF_INET;
 29         servAddr.sin_port = htons(8888);
 30         servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
 31 
 32         //client端 connect 连接
 33         connect(sockfd, (struct sockaddr *)&servAddr, sizeof(servAddr));        //连接 套接字 和 IP
 34 
 35         while(1)
 36         {
 37                 bzero(sendbuf, 128);
 38                 bzero(rcvbuf, 128);
 39                 fgets(sendbuf, 128, stdin);
 40                 send(sockfd, sendbuf, 128, 0);
 41                 rcvLen = recv(sockfd, rcvbuf, 128, 0);  //读取 信息
 42 
 43         if(rcvLen < 0)
 44         {
 45                 printf("ERROR: read failure.\n");
 46                 return -1;
 47         }
 48         if(rcvLen == 0)
 49         {
 50                 printf("Server close connection.\n");
 51                 return -1;
 52         }
 53         printf("receive data[%d bytes]: %s\n", rcvLen, rcvbuf);
 54         }
 55         close(sockfd);
 56 
 57         return 0;
 58 }

执行:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值