我正在学习Winsock,并试图创建一些简单的程序来了解它。我设法创建服务器,可以处理多个连接也管理他们和客户端根据所有教程,它是如何工作的,但:
-
我试图使循环,我检查是否有任何客户端已断开连接,如果有,我想关闭它。
-
我设法写了一些东西,它会检查套接字是否断开连接,但它不会同时连接2个或更多套接字
任何人都可以给我答复如何使工作循环检查通过每个客户端,如果它已断开并关闭套接字?这一切都是为了使一次最多的客户端连接到服务器。提前谢谢。
while (true)
{
ConnectingSocket = accept (ListeningSocket, (SOCKADDR*)&addr, &addrlen);
if (ConnectingSocket!=INVALID_SOCKET)
{
Connections[ConnectionsCounter] = ConnectingSocket;
char *Name = new char[64];
ZeroMemory (Name,64);
sprintf (Name, "%i",ConnectionsCounter);
send (Connections[ConnectionsCounter],Name,64,0);
cout<<"New connection !n";
ConnectionsCounter++;
char data;
if (ConnectionsCounter>0)
{
for (int i=0;i<ConnectionsCounter;i++)
{
if (recv(Connections[i],&data,1, MSG_PEEK))
{
closesocket(Connections[i]);
cout<<"Connection closed.n";
ConnectionsCounter=ConnectionsCounter-1;
}
}
}
}
Sleep(50);
}
似乎您想使用单个线程管理多个连接。对吧?简单地说,套接字通信有两种模式,阻塞和非阻塞。默认为块模式。让我们专注于你的代码:
for (int i=0;i<ConnectionsCounter;i++)
{
if (recv(Connections[i],&data,1, MSG_PEEK))
{
closesocket(Connections[i]);
cout<<"Connection closed.n";
ConnectionsCounter=ConnectionsCounter-1;
}
}
在上面的代码中,您调用了recv函数。直到对方发送了MSG给你,或者对方关闭了链接。所以,如果你现在有两个连接即Connections[0]和Connections[1]。如果你正在接收连接[0],同时,连接[1]已经断开,你不知道。因为您阻塞了recv(Connections[0])。当Connections[0]向您发送消息或它关闭套接字时,则循环继续,最后您检查它是否断开连接,即使它在10分钟前断开连接。
为了解决这个问题,我认为你需要一本书Network Programming for Microsoft Windows。有一些方法,如一线程一套接字模式、异步通信模式、非阻塞模式等。忘了指出bug,注意这里:
closesocket(Connectons[i]);
cout<<"Connection closed.n";
ConnectionsCounter=ConnectionsCounter-1;
让我举个例子来说明。现在我们有两个索引分别为0和1的连接,然后ConnectionsCount应该是2,对吧?当连接[0]断开时,ConnectionsCounter从2变为1。和循环退出,一个新的客户端连接,你保存新的客户端套接字为Connections[ConnectionsCounter(=1)] = ConnectingSocket;哎呀,出问题了。因为已断开的套接字索引为0,索引1被另一个链路使用。处理步骤你正在重用索引1。
为什么不尝试使用vector来保存套接字呢?
希望能有所帮助~