gpt4 book ai didi

java - 套接字编程 : accept() delayed

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:54:31 25 4
gpt4 key购买 nike

我有一个用 C 编写的服务器,它在函数 accept() 处被阻塞并等待新的传入连接。当接受新连接时,它会通过调用 fork() 创建一个新进程。我不使用 epoll,因为每个客户端套接字都由一个独立的进程处理,并且它使用的库之一在多线程环境中崩溃。

服务器代码如下:

srv_sock = init_unix_socket();
listen(srv_sock, 5);
/* Other code which handles SIGCLD. */
while (1) {
log_info("Awaiting new incoming connection.");
clt_sock = accept(srv_sock, NULL, NULL);
if (clt_sock < 0) {
log_err("Error ...");
continue;
}
log_info("Connection %d accepted.", clt_sock);

cld_pid = fork();
if (cld_pid < 0) {
log_err("Failed to create new process.");
close(clt_sock);
continue;
}
if (clt_pid == 0) {
/* Initialize libraries. */
/* Handle client connection ... */
shutdown(clt_sock, SHUT_RDWR);
close(clt_sock);
_exit(0);
}
else {
log_info("Child process created for socket %d.", clt_sock);
close(clt_sock);
}
}

客户端是用 Java 编写的,它使用 junixsocket 库连接到服务器,因为 Java 不支持 Unix 域套接字。当它连接到服务器时,它发送一个请求(一个头+ XML文档)并等待服务器的回复。

客户端代码如下:

File socketFile = new File(UNIX_SOCKET_PATH);
AFUNIXSocket socket = AFUNIXSocket.newInstance();
socket.connect(new AFUNIXSocketAddress(socketFile));

InputStream sis = socket.getInputStream();
OutputStream sos = socket.getOutputStream();
logger.info("Connected with server.");

byte[] requestHeader;
byte[] requestBuffer;

sos.write(requestHeader, 0, requestHeader.length);
logger.info("Header sent.");

sos.write(requestBuffer, 0, requestBuffer.length);
logger.info("Request XML sent.");

sos.flush();

现在的问题是当我有 3 个客户端线程同时连接到服务器时。我总是有 1 个任务在运行,而其他 2 个任务一直在等待,直到第一个任务完成。

我检查了日志。所有 3 个客户端线程都已连接并(几乎)同时向服务器发送请求,但服务器只接受了第一个到达,并延迟了另外两个。根据日志,从客户端的connect到服务器端的accept之间有3分钟的延迟。

起初我认为延迟可能是由某种缓冲区引起的,所以我在每次调用 OutputStream.flush() 之后调用 OutputStream.flush(),但问题是坚持。

我不知道是什么原因导致了这种延迟,请问有什么想法吗?

谢谢。

2016 年 3 月 15 日更新

pstack 显示父进程在我的 SIGCHLD 处理程序中的 waitpid 处被阻止。这可能就是为什么当新的传入连接到达时 accept 没有返回的原因,因为执行过程被信号处理程序中断了。

这是我的信号处理程序的代码:

static void _zombie_reaper (int signum) {
int status;
pid_t child;

if (signum != SIGCHLD) {
return;
}
while ((child = waitpid(-1, &status, WNOHANG)) != -1) {
continue;
}
}

/* In main function */
struct sigaction sig_act;
memset(&sig_act, 0, sizeof(struct sigaction));
sigemptyset(&sig_act.sa_mask);
sig_act.sa_flags = SA_NOCLDSTOP;
sig_act.sa_handler = _zombie_reaper;
if (sigaction(SIGCHLD, &sig_act, NULL) < 0) {
log_err("Failed to register signal handler.");
}

最佳答案

你的waitpid()条件是错误的,你只想在waitpid()收集到子进程时继续调用,所以你需要做

while ((child = waitpid(-1, &status, WNOHANG)) > 0) {
continue;
}

关于java - 套接字编程 : accept() delayed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36004055/

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