gpt4 book ai didi

c - 在c中的套接字编程中读取或写入后没有代码运行

转载 作者:行者123 更新时间:2023-11-30 20:57:24 26 4
gpt4 key购买 nike

我正在用c语言编写一个服务器客户端程序。

服务器首先启动等待客户端,然后客户端“连接”。客户端连接后,它会等待用户的输入,同时服务器运行 read() 以从客户端获取该输入。

这是主要问题。

当 while 循环发现新行字符后,它会将缓冲区中的数据从客户端发送到正在等待读取的服务器。服务器读取,但读取以下的代码不能运行,除非它与缓冲区有关。

如果代码是这样的读取(socket_fd,buff,sizeof(buff));printf("来自客户端的数据:%s", buff);//该行将在终端中运行printf("测试测试测试");//这行永远不会被读取

客户端也是如此。在客户端执行 write() 之后,写入下的任何代码都不会运行。基本上这本质上是一个僵局,两个程序(我认为)只是等待对方的输入。

我不知道这是为什么。也许它正在等待读取更多数据,但这并不能解释为什么它运行打印缓冲区而不打印其他任何内容的代码。

这是从客户端发送和接收数据的代码片段。服务器是用TCP设置的

while(1){
//wait for data from user
bzero(buffer, 256);
printf("Enter the string : ");
n = 0;
while ((buffer[n++] = getchar()) != '\n')
;
write(sockfd, buffer, sizeof(buffer));
printf("WE HERE");
read(sockfd, buffer, sizeof(buffer));
printf("READING THE DATA");
printf("From Server : %s", buffer);
if ((strncmp(buffer, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
}

这是从客户端读取数据并提供响应的服务器代码。

while(1) {
bzero(buffer, 256);


//read the message from the client
read(newsockfd, buffer, sizeof(buffer));
printf("From the client: %s", buffer);

printf("WORKING HERE BEFORE LOWER CASE [SERVER]");
printf("the buffer again: %s", buffer);
lower_string(buffer);
printf("WORKING AFTER THE LOWER CASE [SERVER]");
write(sockfd, buffer, sizeof(buffer));
printf("WRITING TO THE CLIENT");

if (strncmp("exit", buffer, 4) == 0) {
printf("Server Exit...\n");
break;
}
bzero(buffer, 256);
}

最佳答案

您的代码存在许多问题:

  1. 您没有在 printf() 语句的末尾放置换行符,这意味着打印的文本将不可见,直到标准输出缓冲区足够满以强制将其刷新到控制台。这可能会让您对程序的行为感到困惑,因为 printf() 语句正在执行,但您没有及时看到它们的输出。你应该这样做printf("WE HERE\n"); 而不是 printf("WE HERE");

  2. 您没有将 send()recv() 的返回值捕获到变量中,以便您可以检查它们返回的值并执行操作适本地对他们进行。如果你不看返回值,你不知道实际发送或接收了多少字节(可能小于你要求发送或接收的字节数!)并且你不知道是否发生错误或 EOF 情况。

  3. 您应该知道 recv() 将阻塞,直到至少有一个字节的数据可放入传入的缓冲区中,同样,write() 可能会阻塞,直到网络堆栈至少消耗掉传入缓冲区的一个字节。在某些情况下,这确实会导致死锁(例如,如果远程对等点从不发送任何数据,因为它被阻塞在 recv() 中,等待您先向它发送一些数据)。这个问题可以通过各种更高级的技术(例如超时、非阻塞或异步 I/O)来处理,但我不会在这里讨论这些技术。

  4. 将整个 256 字节数组清零,然后接收最多 256 字节意味着,在您一次接收 256 字节数据的情况下,您的数组将不会以 NUL 结尾,并且您将调用 undefined如果您尝试将其用作 C 字符串(例如,将其传递给 printf("%s", buffer);),您最好接收 sizeof(buf) -1 字节(如果您按照第 #2 点中的建议捕获 recv() 的返回值,则只需设置 buffer[numBytesReceived] = '\0 '; 之后,这是确保字符串以 NUL 结尾的更有效方法,而不是不必要地清除所有 256 个字节)

  5. 请注意,您不能假设您将在一次 recv() 调用中 recv() 接收整个字符串。在这个玩具程序中不太可能发生(除非您的网络条件非常糟糕),但一般来说,发送者可以 send() 例如“123456789”,接收者的第一个 recv() 调用得到“1234”,然后第二个 recv() 调用得到“567”,然后第三个调用得到“89” ,或字符串子集的任何其他组合。接收方保证按顺序接收所有字节,但不保证一次性接收所有字节。生产级代码需要足够智能才能正确处理该问题。

关于c - 在c中的套接字编程中读取或写入后没有代码运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60078096/

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