源码地址:https://github.com/shaojunlv/socket-select

客户端代码:

/**************************************************************************/
/* Generic client example is used with connection-oriented server designs */
/**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>#define SERVER_PORT  12345 //端口号main (int argc, char *argv[])
{int    len, rc;int    sockfd;char   send_buf[80];char   recv_buf[80];struct sockaddr_in   addr;/*************************************************//* Create an AF_INET stream socket               *//*************************************************/sockfd = socket(AF_INET, SOCK_STREAM, 0); //建立套接字if (sockfd < 0){perror("socket");exit(-1);}/*************************************************//* Initialize the socket address structure       *//*************************************************/memset(&addr, 0, sizeof(addr));             //分配内存addr.sin_family      = AF_INET;              //ipv4addr.sin_addr.s_addr = htonl(INADDR_ANY);    //接收客户端的类型addr.sin_port        = htons(SERVER_PORT);   //使用的端口/*************************************************//* Connect to the server                         *//*************************************************/rc = connect(sockfd,                           //将套接字与地址建立链接(struct sockaddr *)&addr,sizeof(struct sockaddr_in));if (rc < 0){perror("connect");close(sockfd);exit(-1);}printf("Connect completed.socketfd is %d .rc is %d \n",sockfd,rc);/*************************************************//* Enter data buffer that is to be sent          *//*************************************************/printf("Enter message to be sent:\n");gets(send_buf);/*************************************************//* Send data buffer to the worker job            *//*************************************************/len = send(sockfd, send_buf, strlen(send_buf) + 1, 0);  //向端口发送if (len != strlen(send_buf) + 1){perror("send");close(sockfd);exit(-1);}printf("%d bytes sent\n", len);/*************************************************//* Receive data buffer from the worker job       *//*************************************************/len = recv(sockfd, recv_buf, sizeof(recv_buf), 0);        //从端口接收if (len != strlen(send_buf) + 1){perror("recv");close(sockfd);exit(-1);}printf("%d bytes received\n", len);/*************************************************//* Close down the socket                         *//*************************************************/close(sockfd);
}

服务器端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>#define SERVER_PORT  12345#define TRUE             1
#define FALSE            0main (int argc, char *argv[])
{int    i, len, rc, on = 1;int    listen_sd, max_sd, new_sd;int    desc_ready, end_server = FALSE;int    close_conn;char   buffer[80];struct sockaddr_in   addr;struct timeval       timeout;fd_set        master_set, working_set;/*************************************************************//* Create an AF_INET stream socket to receive incoming       *//* connections on                                            *//*************************************************************/listen_sd = socket(AF_INET, SOCK_STREAM, 0);if (listen_sd < 0){perror("socket() failed");exit(-1);}/*************************************************************//* Allow socket descriptor to be reuseable                   *//*************************************************************/rc = setsockopt(listen_sd, SOL_SOCKET,  SO_REUSEADDR,(char *)&on, sizeof(on));if (rc < 0){perror("setsockopt() failed");close(listen_sd);exit(-1);}/*************************************************************//* Set socket to be non-blocking.  All of the sockets for    *//* the incoming connections will also be non-blocking since  *//* they will inherit that state from the listening socket.   *//*************************************************************/rc = ioctl(listen_sd, FIONBIO, (char *)&on);if (rc < 0){perror("ioctl() failed");close(listen_sd);exit(-1);}/*************************************************************//* Bind the socket                                           *//*************************************************************/memset(&addr, 0, sizeof(addr));addr.sin_family      = AF_INET;addr.sin_addr.s_addr = htonl(INADDR_ANY);addr.sin_port        = htons(SERVER_PORT);rc = bind(listen_sd,(struct sockaddr *)&addr, sizeof(addr));if (rc < 0){perror("bind() failed");close(listen_sd);exit(-1);}/*************************************************************//* Set the listen back log                                   *//*************************************************************/rc = listen(listen_sd, 32);if (rc < 0){perror("listen() failed");close(listen_sd);exit(-1);}/*************************************************************//* Initialize the master fd_set                              *//*************************************************************/FD_ZERO(&master_set);max_sd = listen_sd;FD_SET(listen_sd, &master_set);/*************************************************************//* Initialize the timeval struct to 3 minutes.  If no        *//* activity after 3 minutes this program will end.           *//*************************************************************/timeout.tv_sec  = 3 * 60;timeout.tv_usec = 0;/*************************************************************//* Loop waiting for incoming connects or for incoming data   *//* on any of the connected sockets.                          *//*************************************************************/do{/**********************************************************//* Copy the master fd_set over to the working fd_set.     *//**********************************************************/memcpy(&working_set, &master_set, sizeof(master_set));/**********************************************************//* Call select() and wait 5 minutes for it to complete.   *//**********************************************************/printf("listen_sd is %d ",listen_sd);printf("Waiting on select()...\n");rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);/**********************************************************//* Check to see if the select call failed.                *//**********************************************************/if (rc < 0){perror("  select() failed");break;}/**********************************************************//* Check to see if the 5 minute time out expired.         *//**********************************************************/if (rc == 0){printf("  select() timed out.  End program.\n");break;}/**********************************************************//* One or more descriptors are readable.  Need to         *//* determine which ones they are.                         *//**********************************************************/desc_ready = rc;for (i=0; i <= max_sd  &&  desc_ready > 0; ++i){/*******************************************************//* Check to see if this descriptor is ready            *//*******************************************************/if (FD_ISSET(i, &working_set)){/****************************************************//* A descriptor was found that was readable - one   *//* less has to be looked for.  This is being done   *//* so that we can stop looking at the working set   *//* once we have found all of the descriptors that   *//* were ready.                                      *//****************************************************/desc_ready -= 1;/****************************************************//* Check to see if this is the listening socket     *//****************************************************/if (i == listen_sd){printf("  Listening socket is readable\n");/*************************************************//* Accept all incoming connections that are      *//* queued up on the listening socket before we   *//* loop back and call select again.              *//*************************************************/do{/**********************************************//* Accept each incoming connection.  If       *//* accept fails with EWOULDBLOCK, then we     *//* have accepted all of them.  Any other      *//* failure on accept will cause us to end the *//* server.                                    *//**********************************************/new_sd = accept(listen_sd, NULL, NULL);if (new_sd < 0){if (errno != EWOULDBLOCK){perror("  accept() failed");end_server = TRUE;}break;}/**********************************************//* Add the new incoming connection to the     *//* master read set                            *//**********************************************/printf("  New incoming connection - %d\n", new_sd);FD_SET(new_sd, &master_set);if (new_sd > max_sd)max_sd = new_sd;/**********************************************//* Loop back up and accept another incoming   *//* connection                                 *//**********************************************/} while (new_sd != -1);}/****************************************************//* This is not the listening socket, therefore an   *//* existing connection must be readable             *//****************************************************/else{printf("  Descriptor %d is readable\n", i);close_conn = FALSE;/*************************************************//* Receive all incoming data on this socket      *//* before we loop back and call select again.    *//*************************************************/do{/**********************************************//* Receive data on this connection until the  *//* recv fails with EWOULDBLOCK.  If any other *//* failure occurs, we will close the          *//* connection.                                *//**********************************************/rc = recv(i, buffer, sizeof(buffer), 0);if (rc < 0){if (errno != EWOULDBLOCK){perror("  recv() failed");close_conn = TRUE;}break;}/**********************************************//* Check to see if the connection has been    *//* closed by the client                       *//**********************************************/if (rc == 0){printf("  Connection closed\n");close_conn = TRUE;break;}/**********************************************//* Data was recevied                          *//**********************************************/len = rc;printf("  %d bytes received\n", len);/**********************************************//* Echo the data back to the client           *//**********************************************/rc = send(i, buffer, len, 0);if (rc < 0){perror("  send() failed");close_conn = TRUE;break;}} while (TRUE);/*************************************************//* If the close_conn flag was turned on, we need *//* to clean up this active connection.  This     *//* clean up process includes removing the        *//* descriptor from the master set and            *//* determining the new maximum descriptor value  *//* based on the bits that are still turned on in *//* the master set.                               *//*************************************************/if (close_conn){close(i);FD_CLR(i, &master_set);if (i == max_sd){while (FD_ISSET(max_sd, &master_set) == FALSE)max_sd -= 1;}}} /* End of existing connection is readable */} /* End of if (FD_ISSET(i, &working_set)) */} /* End of loop through selectable descriptors */} while (end_server == FALSE);/*************************************************************//* Cleanup all of the sockets that are open                  *//*************************************************************/for (i=0; i <= max_sd; ++i){if (FD_ISSET(i, &master_set))close(i);}
}

整体看这个代码似曾相识,不存在抄袭,这仅仅是tcp的一种套路而已。

源码完全注释:socket select相关推荐

  1. 2 Keil自带的8051汇编boot源码解析注释

    本仓库相关网址: CSDN文章地址(待添加) Gitee工程和源码地址 - https://gitee.com/langcai1943/8051-from-boot-to-application 相关 ...

  2. java 注释工具栏_eclipse/intellij idea 查看java源码和注释方法

    工作三年了,一直不知道怎么用IDE查看第三方jar包的源码和注释,惭愧啊!看源码还好些,itellij idea自带反编译器,eclipse装个插件即可,看注释就麻烦了,总不能去找api文档吧!现在终 ...

  3. ExcelToHtmlTable转换算法:将Excel转换成Html表格并展示(项目源码+详细注释+项目截图)...

    功能概述 Excel2HtmlTable的主要功能就是把Excel的内容以表格的方式,展现在页面中. Excel的多个Sheet对应页面的多个Tab选项卡. 转换算法的难点在于,如何处理行列合并,将E ...

  4. Nginx源码完全注释(4)ngx_queue.h / ngx_queue.c

    Nginx源码完全注释(4)ngx_queue.h / ngx_queue.c 作者:柳大·Poechant(钟超) 邮箱:zhongchao.ustc#gmail.com(# -> @) 博客 ...

  5. Nginx源码完全注释(1)ngx_alloc.h / ngx_alloc.c

    Nginx源码完全注释(1)ngx_alloc.h / ngx_alloc.c 作者:柳大·Poechant 时间:2012年7月1日 博客:Blog.CSDN.net/Poechant 首先看 ng ...

  6. html5连连看源码解析,JS连连看源码完美注释版(推荐)

    JS连连看源码完美注释版 table{ border-collapse: collapse; } td{ border: solid #ccc 1px; height: 36px; width: 36 ...

  7. 电子木鱼网页版(教学+源码带注释)

    近日在网上经常看见电子木鱼的案例,但都是做的小程序,本人就突发奇想,使用css和JavaScript在网页中实现这个功能.于是便有了这个文章.有细致的讲解,也把源码都放在了最后,没有耐心的小伙伴可以直 ...

  8. 微信App支付源码坑注释

    微信App支付源码&坑注释 部分的代码,因为代码是copy的我自己代码,然后再进行部分的编辑和注释,所以在使用的时候有可能有欠缺,不过整体来说,应该不影响使用的.如果有疑问,可以留言.在微信A ...

  9. C++ 一元二次方程求根,直输方程可含分数(附源码、注释)

    写在前面:翻看以前做的程设题,偶然看到这个期末考没做出来的硬茬(当时是一元一次求根),重新写了个升级版,弥补一下遗憾. 力扣题库"求解方程"可过,改一下函数名即可. 目录 格式控制 ...

  10. Vue 合同模板_vue源码逐行注释分析+40多m的vue源码程序流程图思维导图

    vue源码业余时间差不多看了一年,以前在网上找帖子,发现很多帖子很零散,都是一部分一部分说,断章的很多,所以自己下定决定一行行看,经过自己坚持与努力,现在基本看完了,差ddf那部分,因为考虑到自己要换 ...

最新文章

  1. Intellij idea workflow 工作流插件安装
  2. USTC English Club Note20171016(2)
  3. safari浏览器_用了这么多年iPhone才知道,原来?Safari浏览器这么好用
  4. python输出日志到文件_【已解决】Python中,如何让多个py文件的logging输出到同一个日志log文件...
  5. 20145313张雪纯《信息安全系统设计基础》第11周学习总结
  6. 均线带角度的指标_选股指标:均线角度并列向上,量能倍增飞扬趋势明显,短线操作可考虑...
  7. [转载]流行视频格式讲解
  8. Python list倒序遍历(reversed )
  9. mavros 基于体轴坐标系下的无人机行人跟踪
  10. Java并发编程-线程安全基础
  11. 在mac上用文本编辑器写java源代码
  12. 【MATLAB图像读取】
  13. TMS320C64x DSP L1 L2 Cache架构(1)——C64x Cache Architecture
  14. 深度解读“人类首次实现室温超导”:思路并无突破,中国并不落后-1
  15. vim中实现大小写转换
  16. wingide python_Python开发利器WingIDE破解方法
  17. referenced before assignment
  18. Android studio录屏按钮不能用怎么办
  19. php开发微信手册,PHP技术开发微信公众平台
  20. 网上学python靠谱吗?

热门文章

  1. OLTP和OLAP的区别
  2. JAVA遍历map元素
  3. linux修改ip dhcp,Linux下在静态IP与动态DHCP之间切换的脚本
  4. mysql 统计查询总数_如何一眼识别MySQL选择哪种查询计划(上)
  5. centos7安装详细图解_开封温包规格,电热执行器安装详细图解
  6. 超强干货素材!制作平面设计专辑模板
  7. 精选素材模板丨极简风简历模板
  8. java socket 回调函数_请问Java网络编程如何在不使用多线程的情况下实现异步返回?...
  9. mro python_Python新式类的方法解析顺序MRO与Super
  10. win系统流畅度测试软件,视频对比:老电脑装Win7、Win10流畅性测试