gpt4 book ai didi

c - Linux 套接字 : How to make send() wait for recv()

转载 作者:太空狗 更新时间:2023-10-29 16:52:42 26 4
gpt4 key购买 nike

我正在使用 TCP 协议(protocol)制作一个简单的客户端-服务器应用程序。

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

换句话说。是否可以让每个 send() 等待对方的 recv() 才能调用另一个 send()

说明我的问题。我将在这里发布一个简单的代码:

客户端.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;
}

服务器.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, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', 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, '\0', 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() 可能会堆积在一起并被服务器作为一个整体接收。 (我的解释对吗?)

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

那么有没有更好更稳固的方式让两端互相通信,保证一个send()发送的msg被一个recv()接收>?

最佳答案

客户端.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;
}

关于c - Linux 套接字 : How to make send() wait for recv(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19794764/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com