Linux socket:如何使send()等待recv()

前端之家收集整理的这篇文章主要介绍了Linux socket:如何使send()等待recv()前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用TCP协议创建一个简单的客户端 – 服务器应用程序.

我知道默认情况下. recv()将阻塞,直到另一方调用send()到此套接字.
但是有可能send()阻塞自己,直到另一方已经recv()编辑了msg而不是将send()保持到传出队列,然后找到另一侧recv()得到了一大堆由多个发送的消息发送()■

换一种说法.是否有可能让每个send()等待另一方的recv()才能调用另一个send()?

说清楚我的问题.我将在这里发布一个简单的代码

client.c

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <poll.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h> 

int main(int argc,char *argv[])
{
    int sockfd = 0;
    char sendBuff[1024];
    struct sockaddr_in serv_addr;
    int i;

    if(argc != 2)
    {
        printf("\n Usage: %s <ip of server> \n",argv[0]);
        return 1;
    } 

    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    } 

    memset(&serv_addr,'0',sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(5000); 

    if(inet_pton(AF_INET,argv[1],&serv_addr.sin_addr)<=0)
    {
        printf("\n inet_pton error occured\n");
        return 1;
    } 

    if( connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
    {
        printf("\n Error : Connect Failed \n");
        return 1;
    }

    do{
        memset(sendBuff,'\0',sizeof(sendBuff));
        sprintf(sendBuff,"This is line %d",i);
        send(sockfd,sendBuff,strlen(sendBuff),0);
        //sleep(1);
    }while(++i<100);

    return 0;
}

server.c

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h> 

int main(int argc,char *argv[])
{
    int listenfd = 0,connfd = 0;
    struct sockaddr_in serv_addr; 

    char sendBuff[1025];
    char recvBuff[100];

    int i = 0;

    listenfd = socket(AF_INET,0);
    memset(&serv_addr,sizeof(serv_addr));
    memset(sendBuff,sizeof(sendBuff)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(5000); 

    bind(listenfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)); 

    listen(listenfd,10); 

    connfd = accept(listenfd,(struct sockaddr*)NULL,NULL); 

    do{  
        memset(recvBuff,sizeof(recvBuff));
        recv(connfd,recvBuff,sizeof(recvBuff),0);
        printf( "%s\n",recvBuff);
    }while(++i<100); 

    return 0;
}

我期望在服务器端的结果是打印:

This is line 0
This is line 1
This is line 2
This is line 3
...

但是,实际结果是这样的:

This is line 0
This is line 1This is line 2This is line3This is line 4
This is line 5This is line 6This is line 7This is line 8This is line 9This is line 10
This is line 11This is line 12...

但是这很容易解释:当客户端发出send()时,它没有等待服务器端的recv()完成,并且由于某种原因,服务器端recv()循环比客户端发送慢().因此,客户端上的几个send()可以堆叠在一起并由服务器作为整体接收. (我的解释是对的吗?)

实际上似乎有一个非常愚蠢和松散的解决方案.只需在循环中的每个send()之后添加一个sleep(1)(就像我注释掉的那样).我知道这将使代码效率非常低,并且如果recv()循环将花费更长的时间来实现一些其他复杂的操作(当程序变大时这显然是不可预测的),这将花费超过1秒.此解决方案失败!

那么是否有更好的方法让双方相互通信以确保由单个recv()接收的单个send()发送的消息?

解决方法

client.c
while(condition)
{
  send() from client;
  recv() from server;
}

server.c

recv() from client;
while(condition)
{
  send() from server; //acknowledge to client
  recv() from client;
}

猜你在找的Linux相关文章