源码完全注释:socket select
源码地址: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相关推荐
- 2 Keil自带的8051汇编boot源码解析注释
本仓库相关网址: CSDN文章地址(待添加) Gitee工程和源码地址 - https://gitee.com/langcai1943/8051-from-boot-to-application 相关 ...
- java 注释工具栏_eclipse/intellij idea 查看java源码和注释方法
工作三年了,一直不知道怎么用IDE查看第三方jar包的源码和注释,惭愧啊!看源码还好些,itellij idea自带反编译器,eclipse装个插件即可,看注释就麻烦了,总不能去找api文档吧!现在终 ...
- ExcelToHtmlTable转换算法:将Excel转换成Html表格并展示(项目源码+详细注释+项目截图)...
功能概述 Excel2HtmlTable的主要功能就是把Excel的内容以表格的方式,展现在页面中. Excel的多个Sheet对应页面的多个Tab选项卡. 转换算法的难点在于,如何处理行列合并,将E ...
- Nginx源码完全注释(4)ngx_queue.h / ngx_queue.c
Nginx源码完全注释(4)ngx_queue.h / ngx_queue.c 作者:柳大·Poechant(钟超) 邮箱:zhongchao.ustc#gmail.com(# -> @) 博客 ...
- 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 ...
- html5连连看源码解析,JS连连看源码完美注释版(推荐)
JS连连看源码完美注释版 table{ border-collapse: collapse; } td{ border: solid #ccc 1px; height: 36px; width: 36 ...
- 电子木鱼网页版(教学+源码带注释)
近日在网上经常看见电子木鱼的案例,但都是做的小程序,本人就突发奇想,使用css和JavaScript在网页中实现这个功能.于是便有了这个文章.有细致的讲解,也把源码都放在了最后,没有耐心的小伙伴可以直 ...
- 微信App支付源码坑注释
微信App支付源码&坑注释 部分的代码,因为代码是copy的我自己代码,然后再进行部分的编辑和注释,所以在使用的时候有可能有欠缺,不过整体来说,应该不影响使用的.如果有疑问,可以留言.在微信A ...
- C++ 一元二次方程求根,直输方程可含分数(附源码、注释)
写在前面:翻看以前做的程设题,偶然看到这个期末考没做出来的硬茬(当时是一元一次求根),重新写了个升级版,弥补一下遗憾. 力扣题库"求解方程"可过,改一下函数名即可. 目录 格式控制 ...
- Vue 合同模板_vue源码逐行注释分析+40多m的vue源码程序流程图思维导图
vue源码业余时间差不多看了一年,以前在网上找帖子,发现很多帖子很零散,都是一部分一部分说,断章的很多,所以自己下定决定一行行看,经过自己坚持与努力,现在基本看完了,差ddf那部分,因为考虑到自己要换 ...
最新文章
- Intellij idea workflow 工作流插件安装
- USTC English Club Note20171016(2)
- safari浏览器_用了这么多年iPhone才知道,原来?Safari浏览器这么好用
- python输出日志到文件_【已解决】Python中,如何让多个py文件的logging输出到同一个日志log文件...
- 20145313张雪纯《信息安全系统设计基础》第11周学习总结
- 均线带角度的指标_选股指标:均线角度并列向上,量能倍增飞扬趋势明显,短线操作可考虑...
- [转载]流行视频格式讲解
- Python list倒序遍历(reversed )
- mavros 基于体轴坐标系下的无人机行人跟踪
- Java并发编程-线程安全基础
- 在mac上用文本编辑器写java源代码
- 【MATLAB图像读取】
- TMS320C64x DSP L1 L2 Cache架构(1)——C64x Cache Architecture
- 深度解读“人类首次实现室温超导”:思路并无突破,中国并不落后-1
- vim中实现大小写转换
- wingide python_Python开发利器WingIDE破解方法
- referenced before assignment
- Android studio录屏按钮不能用怎么办
- php开发微信手册,PHP技术开发微信公众平台
- 网上学python靠谱吗?
热门文章
- OLTP和OLAP的区别
- JAVA遍历map元素
- linux修改ip dhcp,Linux下在静态IP与动态DHCP之间切换的脚本
- mysql 统计查询总数_如何一眼识别MySQL选择哪种查询计划(上)
- centos7安装详细图解_开封温包规格,电热执行器安装详细图解
- 超强干货素材!制作平面设计专辑模板
- 精选素材模板丨极简风简历模板
- java socket 回调函数_请问Java网络编程如何在不使用多线程的情况下实现异步返回?...
- mro python_Python新式类的方法解析顺序MRO与Super
- win系统流畅度测试软件,视频对比:老电脑装Win7、Win10流畅性测试