Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C&;linux:重用封闭套接字/替代方案_C_Linux_Sockets_File Descriptor - Fatal编程技术网

C&;linux:重用封闭套接字/替代方案

C&;linux:重用封闭套接字/替代方案,c,linux,sockets,file-descriptor,C,Linux,Sockets,File Descriptor,我正在为一个游戏制作一个多线程tcp服务器 我在套接字方面遇到了问题,当服务器停止接收来自客户端的信息时,我关闭我确实接受()的套接字(如下所示),然后退出线程,并通知主线程插槽不再忙 clientData.client[next] ) = accept(server,(struct sockaddr *)&client_address,&t)); (此处有错误检查,但我有) 但是,当我再次尝试进入该插槽时,它给了我一个错误的文件描述符,我进行了一些挖掘,发现close()完

我正在为一个游戏制作一个多线程tcp服务器

我在套接字方面遇到了问题,当服务器停止接收来自客户端的信息时,我关闭我确实接受()的套接字(如下所示),然后退出线程,并通知主线程插槽不再忙

clientData.client[next] ) = accept(server,(struct sockaddr *)&client_address,&t)); 
(此处有错误检查,但我有)

但是,当我再次尝试进入该插槽时,它给了我一个错误的文件描述符,我进行了一些挖掘,发现close()完全破坏了一个套接字,并使其在运行的其余部分无法使用(如果我错了,请纠正我)

现在让我困惑的是:

a) 我仍然可以使用套接字来接受,并且我得到了一个文件描述符,问题是当我尝试在套接字上使用recv()时,就像这样

n = (recv(c->client[threadLocal], str, 100, 0); 
(此处有错误检查,但我有)

b) 当我到达套接字阵列中的最后一个插槽时,我可以很好地重用套接字,这很奇怪,如果在第一次运行时出现问题,但不是在最后一次运行时,我感觉我错过了理解某些东西

c) 如何使套接字可重复使用?或者,除了制作可在程序运行的其余部分重用的套接字之外,还有什么好的替代方法呢

所有的帮助都是非常感谢的,因为老实说,我对这里发生的事情非常困惑

编辑:好的,这是我想做的一个小例子。我在结构中有一个套接字数组,表示服务器上的插槽。我意识到制作一个包含套接字的播放器的结构列表可能会更容易,所以当有人加入时,你可以创建一个新的结构,但我现在不想这样做,因为这需要大量的工作,但如果没有选择,我会这样做

struct clientData{
 int clientSocket[maxplayers];
 //and some other stuff
};
当一个玩家加入时,他们获取列表中第一个可用的套接字,并在其上执行accept(),当客户端断开连接时,我希望该套接字可供另一个客户端声明。基本上,我希望旧客户机放弃close()或类似的东西,而稍后连接的新客户机能够重用阵列中的这个套接字/位置

我正在寻找一种方法来重置一个插座,以便它可以在需要时再次使用。
我希望这能让事情更容易理解,再次感谢。

您混淆了两种不同类型的套接字

有监听插座。当您调用
listen
时,将一个套接字转换为侦听套接字。然后,您可以在侦听套接字上调用
accept
,以连接套接字。只有当您不想再监听新的连接时(至少,不在该端口上),才可以
关闭
侦听套接字。您永远不会在侦听套接字上调用
send
recv
,因为它们没有连接到任何东西

有连接的插座。当您在监听插座上呼叫
accept
时,您会得到一个全新的连接插座。您可以在连接的插座上调用
send
recv
,与另一端通话。当您使用完已连接的插座后,应
关闭它。然后,连接的插座将被完全破坏

您可以继续在侦听套接字上调用
accept
,以便在调用这些已连接套接字上的
send
recv
close
时获得更多已连接的套接字,因为您需要这样做来管理各种连接

您还可能将套接字与套接字句柄混淆。有时人们确实使用“套接字”一词来表示两者。但这里有套接字本身,它是一个通信端点,可以连接也可以不连接,还有套接字句柄,它是一个用于引用特定套接字的数字

您不能重用实际套接字——它是死连接的端点。您可以重复使用套接字句柄。调用
close
后,无论实际套接字发生什么情况,都可以重用句柄。下次调用
socket
accept
可能会得到相同的句柄。(但不要假设它会,只要存储句柄即可。)

当一个玩家加入时,他们获取列表中第一个可用的套接字,并在其上执行accept(),当客户端断开连接时,我希望该套接字可供另一个客户端声明。基本上,我希望旧客户机放弃close()或类似的东西,而稍后连接的新客户机能够重用阵列中的这个套接字/位置

新客户端可以重用套接字句柄和数组中的位置。在侦听套接字上调用
accept
,并将新连接的套接字句柄存储在空闲的阵列插槽中

我想你的第一句话的措辞有点糟糕。我怀疑您的意思是这样的:“对于要加入服务器的玩家,数组中分配了一个插槽。线程在服务器的侦听套接字上调用
accept
,并将返回的套接字描述符存储在数组中的该插槽中。”


完成连接后,
关闭
连接的插槽,并将阵列中的插槽标记为空闲。然后,您可以在侦听套接字上再次调用
accept
,可能会返回相同的套接字描述符,但无论哪种方式,都可以将新连接的套接字存储在阵列中的该插槽中并处理新客户端。

您混淆了两种不同类型的套接字

有监听插座。当您调用
listen
时,将一个套接字转换为侦听套接字。然后,您可以在侦听套接字上调用
accept
,以连接套接字。只有当您不想再监听新的连接时(至少,不在该端口上),才可以
关闭
侦听套接字。您永远不会在侦听套接字上调用
send
recv
,因为它们没有连接到任何东西

有连接的插座。当您在监听插座上呼叫
accept
时,您会得到一个全新的连接插座。您可以拨打