网络编程(17)—— 使用recv检查输入缓存是否有数据
2016-10-14 14:09
525 查看
之前一直用linux中的read/write函数进行socket描述符的读写,而在windows中用recv/send进行socket的读写,其实在linux中也有自己的recv/send函数,同样可以进行IO端口的读写操作。
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
recv和send函数的原型和windows中基本类似,这里主要介绍下其最后一个参数flags,用于设置接收数据时指定的可选项信息。
在recv函数中同时设置MSG_PEEK和MSG_DONTWAIT选项,以验证输入缓存上是否存在接收的数据。recv中设置了MSG_PEEK时,即使读取了输入缓冲的数据也不会被删除,一次该选项经常和MSG_DONTWAIT一起使用以非阻塞的方式验证输入缓冲数据是否存在。
peek_send.c:
客户端实现功能向服务器发送一个字符串”123”。
peek_recv.c
服务器端对通过设置MSG_PEEK|MSG_DONTWAIT选项输入缓冲区进行了检查,如果发现存在数据就进行读取。
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL17
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
recv和send函数的原型和windows中基本类似,这里主要介绍下其最后一个参数flags,用于设置接收数据时指定的可选项信息。
在recv函数中同时设置MSG_PEEK和MSG_DONTWAIT选项,以验证输入缓存上是否存在接收的数据。recv中设置了MSG_PEEK时,即使读取了输入缓冲的数据也不会被删除,一次该选项经常和MSG_DONTWAIT一起使用以非阻塞的方式验证输入缓冲数据是否存在。
peek_send.c:
#include<stdio.h> #include<stdlib.h> #include<sys/socket.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> void error_handling(char* message); int main(int argc,char* argv[]) { int sock; struct sockaddr_in serv_addr; if(argc!=3) { printf("Usage %s <address> <port>",argv[0]); exit(1); } //创建socket sock=socket(AF_INET,SOCK_STREAM,0); //准备地址信息 memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr=inet_addr(argv[1]); serv_addr.sin_port=htons(atoi(argv[2])); //连接服务器 if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1) error_handling("connect error"); write(sock,"123",strlen("123")); return 0; } void error_handling(char* message) { fputs(message,stderr); fputc('\n',stderr); exit(1); }
客户端实现功能向服务器发送一个字符串”123”。
peek_recv.c
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include<string.h> #define BUF_SIZE 30 void error_handling(char* message); int main(int argc,char* argv[]) { int serv_sock,clnt_sock; struct sockaddr_in serv_addr,clnt_addr; int clnt_addr_sz; int str_len; char buf[BUF_SIZE]; if(argc!=2) { printf("Usage %s <port>\n",argv[0]); exit(1); } //创建socket serv_sock=socket(AF_INET,SOCK_STREAM,0); //设置地址 memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); serv_addr.sin_port=htons(atoi(argv[1])); //绑定 if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1) error_handling("bind error"); //开启监听 listen(serv_sock,5); //接收链接 clnt_addr_sz=sizeof(clnt_addr); clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_sz); while(1) { str_len=recv(clnt_sock,buf,BUF_SIZE-1,MSG_PEEK|MSG_DONTWAIT); if(str_len>0) break; } buf[str_len]=0; puts(buf); str_len=recv(clnt_sock,buf,BUF_SIZE-1,0); buf[str_len]=0; puts(buf); return 0; } void error_handling(char* message) { fputs(message,stderr); fputc('\n',stderr); exit(1); }
服务器端对通过设置MSG_PEEK|MSG_DONTWAIT选项输入缓冲区进行了检查,如果发现存在数据就进行读取。
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL17
相关文章推荐
- 无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)
- Java基础知识强化之网络编程笔记17:Android网络通信之 使用Http的Post方式读取网络数据(基于HTTP通信技术)
- 没有该栏目数据 可能缓存文件(data/cache/inc_catalog_base.inc)没有更新请检查是否有写入权限
- 检查输入的是否是数字使用keyCode配合onkeypress事件
- ios中使用block回调或代理方式请求网络接口数据(包括网络缓存)
- IO模式设置网络编程常见问题总结—IO模式设置,阻塞与非阻塞的比较,recv参数对性能的影响—O_NONBLOCK(open使用)、IPC_NOWAIT(msgrcv)、MSG_DONTWAIT(re
- 输入框:button的onCLick()用来检查输入的数据是否在数据库中。
- 在MVC中如何在使用 MicrosoftMvcValidation验证的前提下使用 jQuery.Ajax 提交数据的时候检查验证是否通过
- 检查输入的是否是数字使用keyCode配合onkeypress事件
- IO模式设置网络编程常见问题总结—IO模式设置,阻塞与非阻塞的比较,recv参数对性能的影响—O_NONBLOCK(open使用)、IPC_NOWAIT(msgrcv)、MSG_DONTWAIT(re
- 简单编程(一) 新手入门作业 [要求用户输入两个整数,判断第一个整数是否是第二个整数的倍数(使用运算符%)。]
- Java网络编程(13):使用Socket类接收和发送数据
- PreloadDataCache支持预取的数据缓存,使用简单,支持多种缓存算法,支持不同网络类型,扩展性强
- 基于UDP协议的网络编程(使用DatagramSocket发送接收数据)
- 检查网络是否正常使用
- Java网络编程从入门到精通(12):使用isReachable方法探测主机是否可以连通
- 网络编程之:检查URL所指定的图片是否存在(转)
- Java网络编程从入门到精通(13):使用Socket类接收和发送数据
- 在php中直接使用socket编程对memcached缓存进行增删改查数据
- 检查网络是否正常使用