摘抄自
https://blog.csdn.net/lovekun1989/article/details/41042273
https://blog.csdn.net/Ctrl_qun/article/details/52524086
分为无select和有select版本,无select只能一个服务端一个客户端,有select能一个服务端对应多个客户端。
无select,服务端代码

/*socket tcp服务器端*/
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>#define SERVER_PORT 5555/*监听后,一直处于accept阻塞状态,直到有客户端连接,当客户端如数quit后,断开与客户端的连接*/int main()
{//调用socket函数返回的文件描述符int serverSocket;//声明两个套接字sockaddr_in结构体变量,分别表示客户端和服务器struct sockaddr_in server_addr;struct sockaddr_in clientAddr;int addr_len = sizeof(clientAddr);int client;char buffer[200];int iDataNum;//socket函数,失败返回-1//int socket(int domain, int type, int protocol);//第一个参数表示使用的地址类型,一般都是ipv4,AF_INET//第二个参数表示套接字类型:tcp:面向连接的稳定数据传输SOCK_STREAM//第三个参数设置为0if((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 1;}bzero(&server_addr, sizeof(server_addr));//初始化服务器端的套接字,并用htons和htonl将端口和地址转成网络字节序server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);//ip可是是本服务器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//对于bind,accept之类的函数,里面套接字参数都是需要强制转换成(struct sockaddr *)//bind三个参数:服务器端的套接字的文件描述符,if(bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){perror("connect");return 1;}//设置服务器上的socket为监听状态if(listen(serverSocket, 5) < 0) {perror("listen");return 1;}while(1){printf("Listening on port: %d\n", SERVER_PORT);//调用accept函数后,会进入阻塞状态//accept返回一个套接字的文件描述符,这样服务器端便有两个套接字的文件描述符,//serverSocket和client。//serverSocket仍然继续在监听状态,client则负责接收和发送数据//clientAddr是一个传出参数,accept返回时,传出客户端的地址和端口号//addr_len是一个传入-传出参数,传入的是调用者提供的缓冲区的clientAddr的长度,以避免缓冲区溢出。//传出的是客户端地址结构体的实际长度。//出错返回-1client = accept(serverSocket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len);if(client < 0){perror("accept");continue;}printf("\nrecv client data...n");//inet_ntoa   ip地址转换函数,将网络字节序IP转换为点分十进制IP//表达式:char *inet_ntoa (struct in_addr);printf("IP is %s\n", inet_ntoa(clientAddr.sin_addr));printf("Port is %d\n", htons(clientAddr.sin_port));while(1){iDataNum = recv(client, buffer, 1024, 0);if(iDataNum < 0){perror("recv");continue;}buffer[iDataNum] = '\0';if(strcmp(buffer, "quit") == 0)break;printf("%drecv data is %s\n", iDataNum, buffer);send(client, buffer, iDataNum, 0);}}return 0;
}

无select,客户端代码

/*socket tcp客户端*/
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>#define SERVER_PORT 5555/*连接到服务器后,会不停循环,等待输入,输入quit后,断开与服务器的连接*/int main()
{//客户端只需要一个套接字文件描述符,用于和服务器通信int clientSocket;//描述服务器的socketstruct sockaddr_in serverAddr;char sendbuf[200];char recvbuf[200];int iDataNum;if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 1;}serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(SERVER_PORT);//指定服务器端的ip,本地测试:127.0.0.1//inet_addr()函数,将点分十进制IP转换成网络字节序IPserverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0){perror("connect");return 1;}printf("connect with destination host...\n");while(1){printf("Input your world:>");scanf("%s", sendbuf);printf("\n");send(clientSocket, sendbuf, strlen(sendbuf), 0);if(strcmp(sendbuf, "quit") == 0)break;iDataNum = recv(clientSocket, recvbuf, 200, 0);recvbuf[iDataNum] = '\0';printf("recv data of my world is: %s\n", recvbuf);}close(clientSocket);return 0;
}

有select,服务端代码

/*socket tcp服务器端*/
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>#define SERVER_PORT 5555
#define CLIENT_MAX  5
#define BUFFER_SIZE 200int main()
{int serverSocket;struct sockaddr_in server_addr;struct sockaddr_in clientAddr;int addr_len = sizeof(clientAddr);int client, i, ret;char buffer[BUFFER_SIZE];char in_msg[BUFFER_SIZE];char recv_msg[BUFFER_SIZE];int iDataNum;int client_fds[CLIENT_MAX];fd_set server_fd_set;int max_fd = -1;struct timeval tv;if((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 1;}bzero(&server_addr, sizeof(server_addr));//初始化服务器端的套接字,并用htons和htonl将端口和地址转成网络字节序server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);//ip可是是本服务器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//对于bind,accept之类的函数,里面套接字参数都是需要强制转换成(struct sockaddr *)//bind三个参数:服务器端的套接字的文件描述符,if(bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("connect");return 1;}if(listen(serverSocket, 5) < 0) {perror("listen");return 1;}while(1) {tv.tv_sec = 20;tv.tv_usec = 0;FD_ZERO(&server_fd_set);FD_SET(STDIN_FILENO, &server_fd_set);if (max_fd < STDIN_FILENO) {max_fd = STDIN_FILENO;}FD_SET(serverSocket, &server_fd_set);if (max_fd < serverSocket) {max_fd = serverSocket;}for (i = 0; i < CLIENT_MAX; i++) {if (client_fds[i] != 0) {FD_SET(client_fds[i], &server_fd_set);if (max_fd < client_fds[i]) {max_fd = client_fds[i];}}}ret = select(max_fd + 1, &server_fd_set, NULL, NULL, &tv);if (ret < 0) {perror("select error");continue;} else if (ret == 0) {printf("wait ...\n");continue;} else {if (FD_ISSET(STDIN_FILENO, &server_fd_set)) {printf("send msg:");memset(in_msg, 0, BUFFER_SIZE);fgets(in_msg, BUFFER_SIZE, stdin);if (strcmp(in_msg, "quit") == 0) {exit(0);}for (i = 0; i < CLIENT_MAX; i++) {if (client_fds[i] != 0) {printf("send msg to [i:%d] [fd:%d]..\n", i, client_fds[i]);send(client_fds[i], in_msg, BUFFER_SIZE, 0);}}}if (FD_ISSET(serverSocket, &server_fd_set)) {client = accept(serverSocket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len);if(client > 0) {int index =-1;for (i = 0; i < CLIENT_MAX; i++) {if (client_fds[i] == 0) {client_fds[i] = client;index = i;break;}}if (index >= 0) {printf("add client [%d] success, %s:%d.\n", index, inet_ntoa(clientAddr.sin_addr),htons(clientAddr.sin_port));} else {memset(in_msg, 0, BUFFER_SIZE);strcpy(in_msg, "add client fail, reach max client.\n");send(client, in_msg, BUFFER_SIZE, 0);printf("add client fail, reach max client.\n");}}}for (i = 0; i < CLIENT_MAX; i++) {if (client_fds[i] !=0 ) {if (FD_ISSET(client_fds[i], &server_fd_set)) {memset(recv_msg, 0, BUFFER_SIZE);iDataNum = recv(client_fds[i], recv_msg, BUFFER_SIZE, 0);if (iDataNum < 0) {perror("recv");continue;} else if (iDataNum > 0) {if (iDataNum > BUFFER_SIZE) {iDataNum = BUFFER_SIZE;}recv_msg[iDataNum] = '\0';printf("recv %d msg:%s.\n", client_fds[i], recv_msg);} else {FD_CLR(client_fds[i], &server_fd_set);client_fds[i] = 0;  printf("client (%d) exit.\n", i);}}}}}}return 0;
}

有select,客户端代码

/*socket tcp客户端*/
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>#define SERVER_PORT 5555/*连接到服务器后,会不停循环,等待输入,输入quit后,断开与服务器的连接*/int main()
{//客户端只需要一个套接字文件描述符,用于和服务器通信int clientSocket;//描述服务器的socketstruct sockaddr_in serverAddr;char sendbuf[200];char recvbuf[200];int iDataNum;fd_set client_fd_set;struct timeval tv;int ret;if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");return 1;}serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(SERVER_PORT);//指定服务器端的ip,本地测试:127.0.0.1//inet_addr()函数,将点分十进制IP转换成网络字节序IPserverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0){perror("connect");return 1;}printf("connect with destination host...\n");while(1){tv.tv_sec = 20;tv.tv_usec = 0;FD_ZERO(&client_fd_set);  FD_SET(STDIN_FILENO, &client_fd_set);FD_SET(clientSocket, &client_fd_set);ret = select(clientSocket + 1, &client_fd_set, NULL, NULL, &tv);if (ret < 0) {perror("select error");continue;} else if (ret == 0) {//超时continue;} if(FD_ISSET(STDIN_FILENO, &client_fd_set)) {memset(sendbuf, 0, 200);scanf("%s", sendbuf);send(clientSocket, sendbuf, strlen(sendbuf), 0);printf("send msg: %s\n");if(strcmp(sendbuf, "quit") == 0) {break;}}if(FD_ISSET(clientSocket, &client_fd_set)) {memset(recvbuf, 0, 200);iDataNum = recv(clientSocket, recvbuf, 200, 0);if (iDataNum > 0) {recvbuf[iDataNum] = '\0';printf("recv data of my world is: %s", recvbuf);} else if(iDataNum < 0) {printf("接受消息出错!\n");} else {printf("服务器端退出!\n");exit(0); }}}close(clientSocket);return 0;
}

socekt编程-select相关推荐

  1. Python网络编程(4)——异步编程select epoll

    在SocketServer模块的学习中,我们了解了多线程和多进程简单Server的实现,使用多线程.多进程技术的服务端为每一个新的client连接创建一个新的进/线程,当client数量较多时,这种技 ...

  2. java socket编程 select_windows socket编程select模型使用

    int select( int nfds,            //忽略 fd_ser* readfds,    //指向一个套接字集合,用来检测其可读性 fd_set* writefds,   / ...

  3. C++网络编程Select函数用法

    Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如 connect.accept.recv或recvfrom这样的阻塞程序 ...

  4. linux网络编程--select/poll/epoll 详解

    目录 参考链接 epoll函数 close epoll event EL/LT ET Edge Trigger 边沿触发工作模式 LT Level Trigger 水平触发工作模式 epoll 源码解 ...

  5. UNIX网络编程——select函数的并发限制和 poll 函数应用举例

    http://blog.csdn.net/chenxun_2010/article/details/50489577 一.用select实现的并发服务器,能达到的并发数,受两方面限制 1.一个进程能打 ...

  6. linux select shell,linux之shell编程select和case用法

    shell里的select用法: 语法:#i/bin/bash select 变量 in 列表 do 要执行的语句 done 举例: #!/bin/bash echo "What is yo ...

  7. Linux串口编程select方式

    其中串口中的一些重要的设备如下; /*设置等待时间它最小接收字符*/   newtio.c_cc[VTIME] = 1;   newtio.c_cc[VMIN] = 0;   newtio.c_lfl ...

  8. UNIX环境高级编程——select、poll和epoll

    转自:https://blog.csdn.net/ctthuangcheng/article/details/9332431 一.select select目前几乎在所有的平台上支持,其良好跨平台支持 ...

  9. 网络编程(三):Linux 网络IO模型、select、pool、epoll 内核设计

    Linux网络IO模型 同步和异步,阻塞和非阻塞 同步和异步 关注的是调用方是否主动获取结果 同步: 同步的意思就是调用方需要主动等待结果的返回 异步: 异步的意思就是不需要主动等待结果的返回,而是通 ...

最新文章

  1. 分享:Hadoop的Python框架指南
  2. 艾伟:正则表达式30分钟入门教程
  3. mysql+性能优化+命令_MySQL性能优化
  4. P5782-[POI2001]和平委员会【2-SAT】
  5. 三种安防监控摄像机供电方式,如何合理选择?
  6. ARM MOV和 LDR指令关系
  7. 【bzoj2761】【JLOI2011】【不反复数字】【平衡树】
  8. cocos2d精灵教程(三篇)
  9. 目标2020:'鼠'你最棒!
  10. 无线AP网络覆盖两种组网方式
  11. 杀不死的人狼——我读《人月神话》(四)
  12. java输出两个整数的积_如何检查Java中的两个数字相乘是否会导致溢出?
  13. RestTemplate 发送文件
  14. 手把手教你用Execel计算两个矩阵的乘法
  15. Worthington核糖核酸酶B历史和化学性质说明
  16. input标签 各属性解释
  17. ISA防火墙之利用DHCP部署WPAD
  18. Gitea:从SVN迁移到Git
  19. 先进驾驶辅助系统(ADAS) 术语
  20. 2022细胞生物学实验原理复习资料汇总

热门文章

  1. 只需5步,轻松创建HTML5离线应用
  2. python中的PEP是什么?怎么理解?(转)
  3. ZOJ1081 Points Within
  4. django用户认证系统——登录4
  5. linux每天一小步---sed命令详解
  6. 【SQL】sql版Split函数。用于拆分字符串为单列表格
  7. Android 编程下 AlarmManager
  8. 调整Tomcat上的参数提高性能[转]
  9. 英语基础语法(八)-时态
  10. ajax eval html,Ajax eval的应用示例