网络编程(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);

       recvsend函数的原型和windows中基本类似,这里主要介绍下其最后一个参数flags,用于设置接收数据时指定的可选项信息。


    在recv函数中同时设置MSG_PEEKMSG_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


0 0
原创粉丝点击