C unix域套接字编程
我有一个unix域套接字程序,客户端尝试连接到服务器并发送消息,当服务器接受客户端并读取消息时,它将休眠5秒钟并发送另一条消息。在这5秒钟内,如果我使用ctrl+c杀死客户端,服务器将退出。我如何处理这种情况?我的程序如下: 客户:C unix域套接字编程,c,sockets,unix,network-programming,unix-socket,C,Sockets,Unix,Network Programming,Unix Socket,我有一个unix域套接字程序,客户端尝试连接到服务器并发送消息,当服务器接受客户端并读取消息时,它将休眠5秒钟并发送另一条消息。在这5秒钟内,如果我使用ctrl+c杀死客户端,服务器将退出。我如何处理这种情况?我的程序如下: 客户: #include <unistd.h> #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/un.h&g
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#define INFO_SERVER_PATH "/var/info_server_path"
int create_route_client()
{
int client_fd;
int addr_len;
struct sockaddr_un server_addr;
if ((client_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) {
perror("create route info client socket");
return -1;
}
memset(&server_addr, 0, sizeof(struct sockaddr_un));
server_addr.sun_family = AF_LOCAL;
strcpy(server_addr.sun_path, INFO_SERVER_PATH);
addr_len = offsetof(struct sockaddr_un,sun_path) + strlen(server_addr.sun_path);
if (connect(client_fd, (struct sockaddr*)&server_addr, addr_len) < 0) {
perror("socket connect");
return -1;
}
return client_fd;
}
int main(int argc, char const *argv[])
{
char *sendline = "hello server";
char recvline[512];
int client_fd;
int nwrite;
int nread;
client_fd = create_route_client();
assert(client_fd > 0);
nwrite = write(client_fd, sendline, strlen(sendline));
if (nwrite < 0) {
perror("failed to send command to the info server");
close(client_fd);
return 1;
}
nread = read(client_fd, recvline, sizeof(recvline));
if (nread < 0) {
perror("failed to read route state");
close(client_fd);
return 1;
}
recvline[nread] = '\0';
printf("%s\n", recvline);
close(client_fd);
return 0;
}
服务器:
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#define INFO_SERVER_PATH "/var/info_server_path"
int create_command_server()
{
struct sockaddr_un server_addr;
size_t addr_len;
int server_fd;
if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("create socket");
return -1;
}
unlink(INFO_SERVER_PATH);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strcpy(server_addr.sun_path, INFO_SERVER_PATH);
addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(INFO_SERVER_PATH);
if (bind(server_fd, (struct sockaddr*)&server_addr, addr_len) < 0) {
perror("socket bind");
return -1;
}
if (listen(server_fd, 1) < 0) {
perror("socket listen");
return -1;
}
return server_fd;
}
int main(int argc, char const *argv[])
{
int info_server_fd = create_command_server();
char recvline[512];
char *sendline = "hello client";
int nread;
int nwrite;
while (1) {
int info_client_fd = accept(info_server_fd, NULL, NULL);
nread = read(info_client_fd, recvline, 512);
if (nread) {
int i;
for (i = 0; i < 5; i++) {
printf("i = %d\n", i);
sleep(1);
}
nwrite = write(info_client_fd , sendline, strlen(sendline));
printf("nwrite = %d\n", nwrite);
if (nwrite < 0)
perror("failed to send to client");
}
close(info_client_fd);
}
return 0;
}
如果不编译并运行代码,很难准确地说出来,但我猜您会收到一个SIGPIPE信号,因为您在杀死客户机时写入了关闭的连接。接收SIGPIPE的进程的默认操作是终止该进程 您可以使用sigprocmask阻止SIGPIPE信号,或者告诉内核您想要阻止它,忽略它,或者使用sigaction为它注册一个异步信号处理程序。然后,当您调用write时,它将返回-1,errno将设置为eppe。请参阅手册页了解详细信息
有关信号以及如何处理信号的更多信息,请参见信号手册页。但是,请注意,除非您非常小心并确切地知道自己在做什么,否则不应使用异步信号处理程序来处理信号。这是许多错误的根源。到目前为止,最安全的方法是在不需要它们的情况下忽略它们,或者阻止它们并使用同步信号处理方法,如sigwait或特定于Linux的信号。在你的情况下,你不需要它们。写入呼叫将在连接断开时通知您。此代码中没有“5秒睡眠”。也没有任何东西会导致服务器退出。在接受的套接字上也没有任何正确的错误检查或流结束检查。你的问题不清楚是服务器还是客户端应该休眠,也不清楚你描述的是你想要发生的事情,还是你不想发生的事情。你需要提供更多信息。当你说“退出”时,退出到底是因为什么?SIGPIPE?to EJP:这是我用来让服务器在I=0时休眠5秒的方法;i<5;i++{printfi=%d\n,i;sleep1;}到caskey:“quits”表示服务器进程退出,它应该永远在一个while1循环中运行,以接受客户端并向后发送消息。您已经解决了我的六个问题之一。