Я сделал сервер Mutlti-Client, который может получать и отправлять сообщения на сервер, и сервер может отправлять сообщения клиентам, но у меня проблема в том, что клиент A не сможет получить сообщение от клиента B если только клиент А не отправит сообщение, я хочу, чтобы клиенты получали сообщения в любое время, я также хочу набирать команды на сервере, не останавливая поток отправки клиентам и получения сообщений от клиентов
Я пытался переместить std::getline(std::cin, ClientInput);
в другое место в коде, чтобы клиенты могли видеть сообщение, но я заметил в коде, пока l oop не продолжается, потому что есть способ получить ввод пользователя без остановки l oop так можно отправлять и получать сообщения
Это код клиента
int Client::OnCreate()
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL, *ptr = NULL, hints;
char sendbuf[] = "this is a test";
std::vector<SOCKET> ConnectedUser;
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
system("pause");
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo("localhost", DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
system("pause");
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
system("pause");
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
system("pause");
return 1;
}
// Send an initial buffer
std::string ClientInput;
std::cout << "please send a message " << std::endl;
std::getline(std::cin, ClientInput);
do {
if (ClientInput.size() > 0)
{
//send user input to sever
iResult = send(ConnectSocket, ClientInput.c_str(), ClientInput.size(), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
system("pause");
return 1;
}
printf("Bytes Sent: %d\n", iResult);
if (iResult != SOCKET_ERROR)
{
//receive user input from sever
int iUserResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iUserResult > 0)
{
std::cout << "Client receive this message from sever \t" << std::string(recvbuf, 0, iResult) << std::endl;
printf("Bytes received: %d\n", iUserResult);
}
}
//will disconnect from the sever
if (iResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
system("pause");
}
//will disconnect from the sever if user types in logoff
if (ClientInput == "logoff")
{
closesocket(ConnectSocket);
WSACleanup();
printf("Connection closing goodbye sever\n");
system("pause");
}
//close connection if the no user input
if (iResult == 0) {
printf("Connection closed\n");
iResult = shutdown(ConnectSocket, SD_SEND);
}
}
std::getline(std::cin, ClientInput);
} while (ClientInput.size() > 0);
// cleanup
closesocket(ConnectSocket);
system("pause");
WSACleanup();
return 0;
}```
Это код сервера
std::vector<SOCKET> ConnectedUser;
std::vector<int> UserInt;
unsigned __stdcall ClientSession(void *data)
{
char recvbuf[DEFAULT_BUFLEN];
int recvbufleng = DEFAULT_BUFLEN;
int iResult;
int iSendResult;
SOCKET ClientSocket = (SOCKET)data;
struct addrinfo *result = NULL, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
do
{
iResult = recv(ClientSocket, recvbuf, recvbufleng, 0);
///iResult = recv(ClientSocket, recvbuf, sizeof(Player), 0);
std::cout << iResult << std::endl;
if (iResult > 0) {
for (int i = 0; i < ConnectedUser.size(); i++) {
std::cout << "send message to "<< ConnectedUser[i] << std::endl;
//iSendResult = send(ClientSocket, recvbuf, iResult, 0);
iSendResult = send(ConnectedUser[i], recvbuf, iResult, 0);
//ConnectedUser.clear();
//iSendResult = sendto(ConnectedUser[i], recvbuf, iResult, 0, (sockaddr*)&hints, sizeof(hints));
}
std::cout << "ClientSocket" << ClientSocket << std::endl;
if (iSendResult == SOCKET_ERROR)
{
printf("send failed with error: %d \n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Received Message %.*s\n", iResult, recvbuf);
}
else if (iResult == 0)
{
printf("connection closing.... \n");
std::cout << "user logged off" << ClientSocket << std::endl;
}
else
{
printf("recv failed with error: %d \n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
} while (iResult > 0);
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d \n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
closesocket(ClientSocket);
}
int Sever::OnCreate()
{
WSADATA wsaData;
int iResult;
SOCKET ClientSocket = INVALID_SOCKET;
//send to
char recvbuf[DEFAULT_BUFLEN];
int recvbufleng = DEFAULT_BUFLEN;
int iSendResult;
struct addrinfo *result = NULL, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
//create the winsocket
if (iResult != 0) {
printf("WSAStartup failed: %d\n, iResult");
return 1;
}
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
}
SOCKET ListenSocket = INVALID_SOCKET;
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("error at socket(): %d\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
iResult = bind(ListenSocket, result->ai_addr, int(result->ai_addrlen));
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d \n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
printf("Listen failed with error: %d \n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Create the master file descriptor set and zero it
fd_set master;
FD_ZERO(&master);
FD_SET(ListenSocket, &master);
fd_set copy = master;
int socketCount = select(0, ©, nullptr, nullptr, nullptr);
std::cout << " socketCount "<< socketCount << std::endl;
//// Send an initial buffer
//if (socketCount == 0) {
// std::string SeverInput;
// std::cout << "input Server command" << std::endl;
// std::getline(std::cin, SeverInput);
//
// if (SeverInput == "exit")
// {
// closesocket(ClientSocket);
// WSACleanup();
// printf("Connection closing goodbye sever\n");
// }
//}
for (int i = 0; i < socketCount; i++)
{
SOCKET sock = copy.fd_array[i];
if (sock == ListenSocket)
{
//// Accept a new connection
while ((ClientSocket = accept(ListenSocket, NULL, NULL))) {
if (ClientSocket == INVALID_SOCKET) {
printf("Accept failed with error: %d \n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
/* Messtotal.push_back(ClientSocket + "\n");*/
// Add the new connection to the list of connected clients
FD_SET(ClientSocket, &master);
ConnectedUser.push_back(ClientSocket);
std::cout << "client:" << ClientSocket <<" has arrived on sever" <<std::endl;
// Create a new thread for the accepted client (also pass the accepted client socket).
unsigned threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)ClientSocket, 0, &threadID);
}
}
}
WSACleanup();
printf("Server shutting down ");
return 0;
```}