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