gpt4 book ai didi

c - 不用于通信时打开和关闭套接字,只能使用C语言中的select()

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

我正在使用 TCP 编写一个点 2 点聊天应用程序。此应用程序在一个文件中包含客户端和服务器部分。我正在使用 select() 而没有使用 fork()pthread 来处理连接。这是我的应用程序机制,我通过在不同终端上运行应用程序来在同一主机上运行应用程序:

  1. 初始化第一个节点,比如说 P1,作为 ./p2p portToListen
    • 此节点将在 portToListen 上打开一个套接字,假设是 ServerSock1,以监听来自其他对等点的连接。然后进入带有 select() 函数的 while 循环以等待事件。
  2. 初始化第二个节点,比如说 P2,作为 ./p2p portToListen portToConnectTo(我没有在这里指定 IP 地址,因为我在本地机器上运行)。
    • 这也打开了一个新套接字,比方说 ServerSock2,作为第一个“portToListen”,打开一个新套接字,比方说 ClientSock2 连接到第一个。然后进入 while 循环。
    • 当 P2 连接到 P1 时,在 P1 处,它还接受一个带有套接字 ClientSock1 的新连接。
  3. 在设置网络信息和交换网络配置的一些阶段之后(P1 将当前组的信息发送给 P2 并等待 P2 的 ACK),他们可以发送聊天消息。

我的问题是,在这种情况下,我是否需要在每次对等方发送/接收配置信息(不是聊天消息)时关闭套接字。比如P1发送完当前组的信息后,是否需要同时关闭ServerSock1和ClientSock1,P2发送ACK后,是否需要同时关闭ServerSock2和ClientSock2?我认为,ServerSock1,2 应该始终打开吗?并且只在 while 循环之外关闭?

如果我这样做,select() 将不起作用,因为没有用于监视事件的套接字。当两个点要发送聊天消息时,他们需要为 Server 端和 Client 端重新打开套接字,发送信息以建立新的连接,通过调用 (socket(), bind (), listener(), accept(), connect()), 发送一些聊天信息并关闭() 套接字。

此外,如果我想向同一组中的其他对等点发送广播消息,我需要再次打开对等点的套接字,发送聊天消息并close()每个套接字吗?

一般来说,由于我只使用select()close() 和打开套接字的正确方法是什么?如果可能的话,你能给我一个大概的情况吗?非常感谢您的任何意见。非常感谢。下面是我的通用代码:

int main(void)
{
int sock;
fd_set socks;
fd_set readsocks;
int maxsock;
int reuseaddr = 1; /* True */
struct addrinfo hints, *res;

/* Get the address info */
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(NULL, PORT, &hints, &res) != 0) {
perror("getaddrinfo");
return 1;
}

/* Create the socket */
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == -1) {
perror("socket");
return 1;
}

/* Enable the socket to reuse the address */
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1) {
perror("setsockopt");
return 1;
}

/* Bind to the address */
if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
perror("bind");
return 1;
}

freeaddrinfo(res);

/* Listen */
if (listen(sock, BACKLOG) == -1) {
perror("listen");
return 1;
}

/* Set up the fd_set */
FD_ZERO(&socks);
FD_SET(sock, &socks);
FD_SET(0, &socks);
maxsock = sock;

if (argc > 2)
{
clientSock2 = ConnectToServer(IPaddres, portToConnect);
FD_SET(clientSock2, &socks);
}

/* Main loop */
while (1) {
unsigned int s;
readsocks = socks;
if (select(maxsock + 1, &readsocks, NULL, NULL, NULL) == -1) {
perror("select");
return 1;
}
for (s = 0; s <= maxsock; s++) {
if (FD_ISSET(s, &readsocks)) {
printf("socket %d was ready\n", s);
if (s == sock) {
/* New connection */
int clientSock1;
struct sockaddr_in their_addr;
size_t size = sizeof(struct sockaddr_in);
clientSock1 = accept(sock, (struct sockaddr*)&their_addr, &size);
if (newsock == -1) {
perror("accept");
}
else {
printf("Got a connection from %s on port %d\n",
inet_ntoa(their_addr.sin_addr), htons(their_addr.sin_port));
FD_SET(clientSock1, &socks);
if (clientSock1 > maxsock) {
maxsock = clientSock1;
}
}
}
else {
/* Handle send, recv() information of network */
handle(s, &socks);
}
}
}
if (FD_ISSET(0, &readset) { // Handle input
// Sending chatting message
}
}

close(sock);

return 0;
}

最佳答案

您应该重复使用相同的连接。您可能需要调整协议(protocol),以便准确了解请求和响应在何处结束以及新请求和响应在何处开始。

关于c - 不用于通信时打开和关闭套接字,只能使用C语言中的select(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23818839/

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