如何区分两个客户?
How to tell the difference between two clients?
我有一个 客户端 1 发送一些 数据 到 服务器 我想服务器将数据传输到客户端2而不是客户端1.如果 client 1 发送数据不发送回 client 1 而是发送,有什么方法可以告诉服务器我们必须使用不同的客户端套接字到 客户端 2?
当服务器接受 client 1 时,我尝试在其中放入一个列表,但由于某些原因,当服务器接受 client 时,只算作 1 个而不是 2 个2
此函数处理来自客户端的缓冲区
未签名 __stdcall ClientSession(无效*数据)
{
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
int iResult;
int iSendResult;
SOCKET ClientSocket = (SOCKET)data;
do
{
// recv buffer from the client
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
{
//iSendResult = send(ClientSocket, recvbuf, iResult, 0);
iSendResult = send_data(ClientSocket, recvbuf, iResult);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
//receive from the clients
printf("Message %.*s\n", iResult, recvbuf);
}
else if (iResult == 0)
{
printf("Connection closing... \n");
}
else
{
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
} while (iResult > 0);
//接受新客户
while (ClientSocket = accept(ListenSocket, (sockaddr*)&ClientSocket, NULL))
{
printf("Accepted");
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed with errir: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
unsigned threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)ClientSocket, 0, &threadID);
// try add new clients to a list
list<SOCKET> a;
a.push_back(ClientSocket);
for (SOCKET i : a) {
cout << "Hi I'm\n" << ClientSocket;
cout << "MY SIZE\n" << a.size();
}
}
enter code here
您当前的架构为每个客户端启动一个线程:
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)ClientSocket, 0, &threadID);
然后主线程在局部变量:
中保存所有客户端套接字的列表
list<SOCKET> a;
a.push_back(ClientSocket);
然后,每当一个线程收到时,您就让它发送给自己:
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
iSendResult = send_data(ClientSocket, recvbuf, iResult);
很抱歉只是重新措辞,但希望这能让您看到问题所在。有两种主要方法可以解决这个问题:
保留其中的大部分内容,使 list<SOCKET> a;
全局化,并在其周围添加一个互斥体。更改 send_data
调用以发送到列表 a
中的所有客户端,但它本身除外。
忘记每个客户端一个线程的想法。使用非阻塞套接字。有一个主循环尝试从每个客户端接收,然后发送给所有其他客户端。
第一种方法类似于:
// lock mutex
for(auto s:a)
{
if (s != ClientSocket)
{
iSendResult = send_data(s, recvbuf, iResult);
// error handling
}
}
// unlock mutex
和
// lock mutex (same one)
a.push_back(ClientSocket);
for (SOCKET i : a) {
cout << "Hi I'm\n" << ClientSocket;
cout << "MY SIZE\n" << a.size();
}
// unlock mutex
我有一个 客户端 1 发送一些 数据 到 服务器 我想服务器将数据传输到客户端2而不是客户端1.如果 client 1 发送数据不发送回 client 1 而是发送,有什么方法可以告诉服务器我们必须使用不同的客户端套接字到 客户端 2?
当服务器接受 client 1 时,我尝试在其中放入一个列表,但由于某些原因,当服务器接受 client 时,只算作 1 个而不是 2 个2 此函数处理来自客户端的缓冲区 未签名 __stdcall ClientSession(无效*数据) {
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
int iResult;
int iSendResult;
SOCKET ClientSocket = (SOCKET)data;
do
{
// recv buffer from the client
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
{
//iSendResult = send(ClientSocket, recvbuf, iResult, 0);
iSendResult = send_data(ClientSocket, recvbuf, iResult);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
//receive from the clients
printf("Message %.*s\n", iResult, recvbuf);
}
else if (iResult == 0)
{
printf("Connection closing... \n");
}
else
{
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
} while (iResult > 0);
//接受新客户
while (ClientSocket = accept(ListenSocket, (sockaddr*)&ClientSocket, NULL))
{
printf("Accepted");
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed with errir: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
unsigned threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)ClientSocket, 0, &threadID);
// try add new clients to a list
list<SOCKET> a;
a.push_back(ClientSocket);
for (SOCKET i : a) {
cout << "Hi I'm\n" << ClientSocket;
cout << "MY SIZE\n" << a.size();
}
}
enter code here
您当前的架构为每个客户端启动一个线程:
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)ClientSocket, 0, &threadID);
然后主线程在局部变量:
中保存所有客户端套接字的列表list<SOCKET> a;
a.push_back(ClientSocket);
然后,每当一个线程收到时,您就让它发送给自己:
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
iSendResult = send_data(ClientSocket, recvbuf, iResult);
很抱歉只是重新措辞,但希望这能让您看到问题所在。有两种主要方法可以解决这个问题:
保留其中的大部分内容,使
list<SOCKET> a;
全局化,并在其周围添加一个互斥体。更改send_data
调用以发送到列表a
中的所有客户端,但它本身除外。忘记每个客户端一个线程的想法。使用非阻塞套接字。有一个主循环尝试从每个客户端接收,然后发送给所有其他客户端。
第一种方法类似于:
// lock mutex
for(auto s:a)
{
if (s != ClientSocket)
{
iSendResult = send_data(s, recvbuf, iResult);
// error handling
}
}
// unlock mutex
和
// lock mutex (same one)
a.push_back(ClientSocket);
for (SOCKET i : a) {
cout << "Hi I'm\n" << ClientSocket;
cout << "MY SIZE\n" << a.size();
}
// unlock mutex