网络编程(17)—— 使用recv检查输入缓存是否有数据
来源:互联网 发布:天涯与知乎 编辑:程序博客网 时间:2024/05/29 05:11
之前一直用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:
#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 30void 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
- 网络编程(17)—— 使用recv检查输入缓存是否有数据
- Android 检查是否有网络
- 如何检查网络中是否有使用路由
- Android工具类整理(1)检查是否有网络、检查SD卡是否存在
- 检查网络是否正常使用
- 检查网络是否正常使用
- UNIX网络编程——send与recv函数详解
- UNIX网络编程——send与recv函数详解
- 检查omgird是否有数据,检查omgrid是否有选中行(分页情况、不分页情况)
- UNIX网络编程学习(17)--检查套接字选项是否受支持并获取默认值
- socket 网络编程recv()函数错误
- android 检查是否有网络,是否在wifi环境下
- 网络编程 recv()函数
- 检查输入的字符串中是否有空格存在
- python检测变量是否有定义(即使用前检查是否定义好)
- 怎样使用WSAGetLastError?------举例:以网络编程中的recv讲解
- Linux下Socket网络编程send和recv使用注意事项
- Android wiki:04.ConnectivityManager检查是否有可用网络
- 分治法求最小点对距离
- MongoDB——Aggregates(c#实现支持数组字段)
- ffmpeg.c函数结构简单分析(画图)
- GC roots
- 配置apt源
- 网络编程(17)—— 使用recv检查输入缓存是否有数据
- 跨平台Caffe及I/O模型与并行方案(三)
- HTML练习css--制作开心餐厅介绍页面
- TankWar 单机(JAVA版)版本2.2 超级炮弹
- 手机数据库增删改查操作
- 最常用IO流
- C语言矩阵相乘
- 实战Memcached缓存系统(5)Memcached的CAS程序实例
- Struts2标签<1>-HTML标签与struts2标签区别