gpt4 book ai didi

c - Linux 本地通信套接字 : Why is bind() not failing as expected?

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

我有这个服务器应用程序,它设置了一个本地通信流套接字供客户端连接。如果服务器的第二个实例启动并且它尝试绑定(bind)到相同的地址(文件名),bind() 应该失败并返回 EADDRINUSE。但事实并非如此。为什么?

这是展示问题的精简代码:

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>

int make_socket(const char *filename, int style) {
struct sockaddr_un name;
int sock;
size_t size;

sock = socket(PF_LOCAL, style, 0);
if (sock < 0) {
perror("socket");
exit(EXIT_FAILURE);
}

if ((!filename) || (filename[0] == '\0')) {
return sock;
}

name.sun_family = AF_LOCAL;
strncpy(name.sun_path, filename, sizeof(name.sun_path));
name.sun_path[sizeof(name.sun_path) - 1] = '\0';
size = SUN_LEN(&name);

if (bind(sock, (struct sockaddr *) &name, size) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}

return sock;
}

int make_stream_socket(const char *filename) {
return make_socket(filename, SOCK_STREAM);
}

#define TS_SERVER "/tmp/socket-server"

int main(int argc, char *argv[]) {
int sock_server, sock_client;
struct sockaddr_un name_client;
size_t size_name_client;
int i;
fd_set client_set, selected_set;
int quitting = 0;

fprintf(stderr, "Server: starting up\n");
unlink(TS_SERVER);
sock_server = make_stream_socket(TS_SERVER);
fprintf(stderr, "Server: accepting connections on %d\n", sock_server);
if (0 > listen(sock_server, 1)) {
perror("listen(connection requests)");
exit(EXIT_FAILURE);
}
FD_ZERO(&client_set);
FD_SET(sock_server, &client_set);
while (!quitting) {
fprintf(stderr, "Server: waiting for connections\n");
selected_set = client_set; //shallow-clone client_set
if (0 > select(FD_SETSIZE, &selected_set, NULL, NULL, NULL)) {
perror("select(for readability)");
exit(EXIT_FAILURE);
}

fprintf(stderr, "Server: connection(s) received\n");
for (i = 0; i < FD_SETSIZE; ++i) {
if (FD_ISSET(i, &selected_set)) {
if (i == sock_server) {
fprintf(stderr, "Server: accepting connection\n");
size_name_client = sizeof(name_client);
sock_client = accept(sock_server,
(struct sockaddr *) &name_client,
(socklen_t *) &size_name_client);
//Ubuntu Launchpad bug 1463553: accept() returns
// an off-by-one size_name_client
size_name_client = SUN_LEN(&name_client);
if (sock_client < 0) {
perror("accept(connection request)");
exit(EXIT_FAILURE);
}
fprintf(stderr, "Server: accepted connection request from '%s' on %d\n",
name_client.sun_path, sock_client);
quitting = 1;
close(sock_client);
break; //out of the for
} //if (i == sock_server)
} //if (FD_ISSET(i, &selected_set))
} //for
} //while

fprintf(stderr, "Server: shutting down\n");
close(sock_server);
unlink(TS_SERVER);

exit(EXIT_SUCCESS);
}

编译后,从命令行运行第一个实例,然后从另一个命令行运行第二个实例。第二个实例应该在 bind() 上失败,但实际上没有。

最佳答案

因为:

  unlink(TS_SERVER);

您删除现有的套接字文件,这允许在其位置创建一个新的套接字文件。

关于c - Linux 本地通信套接字 : Why is bind() not failing as expected?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30742508/

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