gpt4 book ai didi

c - TCP write() 将 char* 打印到自身而不是仅在第一个套接字连接上缓冲,但在第二个连接上工作正常

转载 作者:太空宇宙 更新时间:2023-11-04 01:43:42 25 4
gpt4 key购买 nike

在客户端第一次连接到服务器套接字时,服务器将输出打印给自己,并让客户端处于阻塞状态。但是第二个客户端开始接收服务器的输出。预期输出到客户端的缓冲区是服务器正常运行时间。

为什么会这样,有没有办法立即将输出发送给Client而不阻塞?

要复制,请在一个终端上运行“ruptimeServer”,然后运行“ruptimeClient [localIPAddress] [serverIPAddress]”。

以下是服务器 I/O 的示例。

[user@linux-3 Lab2]$ ./ruptimeServer 
Awaiting connection.
20:42:05 up 2 days, 17:38, 5 users, load average: 0.00, 0.01, 0.06 <-- buffer
Write Success
Awaiting connection.
Write Success
Awaiting connection.
Write Success
Awaiting connection.
^CCaught Ctrl+C, closing all connections.

下面是客户端的 I/O。

[user@linux-3 Lab2]$ ./ruptimeClient 127.0.0.1 10.24.87.66
Connection Success.
^C
[user@linux-3 Lab2]$ ./ruptimeClient 127.0.0.1 10.24.87.66
Connection Success.
10.24.87.66: 20:42:14 up 2 days, 17:38, 5 users, load average: 0.00, 0.01, 0.06
[user@linux-3 Lab2]$ ./ruptimeClient 127.0.0.1 10.24.87.66
Connection Success.
10.24.87.66: 20:42:18 up 2 days, 17:38, 5 users, load average: 0.00, 0.01, 0.06

下面是服务器的代码。

#include <stdio.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/select.h>

char* get_uptime();
void sig_handl(int sig_num);
int sersock, consock;
int main(int argc, char* argv[]){
struct sockaddr_in serveraddr, clientaddr;
struct sigaction sigIntHandler;
int on = 1;

sigIntHandler.sa_handler = sig_handl;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;

char input_buffer[1024] = {0};
int len = sizeof(clientaddr);

char* IP_ADDRESS = "192.168.254.11";

if((sersock = socket(PF_INET, SOCK_STREAM, 0)) < 0){
perror("socket() error");
exit(1);
}

serveraddr.sin_family = PF_INET;
serveraddr.sin_port = htons(28189);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sersock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0){
perror("bind() error");
exit(1);
}
if(listen(sersock, 10) < 0){
perror("listen() error");
exit(1);
}
char *output;
output = malloc(sizeof(char) * 1024);
signal(SIGINT, sig_handl);
while(1){
printf("Awaiting connection.\n");
if(consock = accept(sersock, (struct sockaddr *)&clientaddr, &len) < 0){
perror("accept() error");
exit(1);
}
output = get_uptime();
if(write(consock, output, 1024) < 0){
perror("write() error");
exit(1);
}
printf("Write Success\n");
close(consock);
}
close(sersock);
}

char * get_uptime(){ //returns uptime on server
char *buffer;
buffer = malloc(sizeof(char) * 1024);
FILE* file = popen("uptime", "r");
fgets(buffer, 100, file);
pclose(file);

return buffer;
}

void sig_handl(int sig_num){
printf("Caught Ctrl+C, closing all connections.\n");
close(consock);
close(sersock);
exit(0);
}

下面是客户端的代码。

#include <stdio.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>

int main(int argc, char* argv[]){
if(argc != 3){
printf("Not enough arguments. To run, \"./ruptimeClient <localhost_IP> <server_IP>\"\n");
return 0;
}
struct sockaddr_in remoteaddr;
char input_buffer[100];
//input_buffer = malloc(sizeof(char) * 100);
int clisock;
char* SERVER_IP = argv[2];

if((clisock = socket(PF_INET, SOCK_STREAM, 0)) < 0){
perror("socket() error");
exit(1);
}

remoteaddr.sin_family = PF_INET;
remoteaddr.sin_port = htons(28189);
remoteaddr.sin_addr.s_addr = inet_addr(SERVER_IP);

if(connect(clisock, (struct sockaddr *)&remoteaddr, sizeof(remoteaddr)) < 0){
perror("Connection failed");
exit(1);
}
printf("Connection Success.\n");
if(read(clisock, input_buffer, 100) < 0){
perror("read() error");
exit(1);
}
//input_buffer = "test";
printf("%s: %s", SERVER_IP, input_buffer);
close(clisock);
return 0;
}

最佳答案

问题出在这里:

if(consock = accept(sersock, (struct sockaddr *)&clientaddr, &len) < 0){

这被解析为就好像你这样写:

if(consock = (accept(sersock, (struct sockaddr *)&clientaddr, &len) < 0)){

因此,consock 最终设置为 0,当它被解释为文件描述符时,意味着标准输入。然后它在第一个客户端(挂起的客户端)之后关闭,因此它可供后续客户端使用,然后重新分配现在可用的 FD 编号。要修复它,请添加显式括号,如下所示:

if((consock = accept(sersock, (struct sockaddr *)&clientaddr, &len)) < 0){

关于c - TCP write() 将 char* 打印到自身而不是仅在第一个套接字连接上缓冲,但在第二个连接上工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57983971/

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