Я только начал с программирования сокетов и просто пытаюсь разрешить клиентам отправлять данные на сервер через TCP-соединение.Затем сервер отправит данные одному фиксированному клиенту, который просто отобразит их.
Я подумал, что это не будет слишком сложно.После того, как я настроил сервер и клиент, который отображает только отправленные данные, я создал несколько клиентов, использующих PuTTY для отправки некоторых данных на сервер, и все прошло отлично.Сервер пересылал сообщения, а фиксированный клиент отображал их.Но теперь, когда я закодировал этих «отправляющих клиентов», я могу заставить одного из этих клиентов отправить только одно сообщение, и после этого все «застряло».Там нет сообщения об ошибке или что-нибудь.Как только я отправляю второе сообщение, консоль не запрашивает у меня третьего сообщения.Я могу только закрыть клиентов и все.
Вот код для клиентов, которые просто отправляют данные:
#include <iostream>
#include <string>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
void main()
{
std::string ipAddress = "127.0.0.1";
int port = 54000;
WSAData data;
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(ver, &data);
if (wsResult != 0)
{
std::cerr << "Can't start Winsock, Err #" << wsResult << std::endl;
return;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
std::cerr << "Can't create socket, Err #" << WSAGetLastError() << std::endl;
WSACleanup();
return;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR)
{
std::cerr << "Can't connect to server, Err #" << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return;
}
char buf[4096];
std::string userInput;
do
{
std::cout << "> ";
std::getline(std::cin, userInput);
if (userInput.size() > 0) {
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult != SOCKET_ERROR)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0)
{
std::cout << "SERVER> " << std::string(buf, 0, bytesReceived) << std::endl;
}
}
}
} while (userInput.size() > 0);
closesocket(sock);
WSACleanup();
}
Это код для клиента, который должен просто отображать то, что было отправлено другими клиентами:
#include <iostream>
#include <ws2tcpip.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")
void main() {
std::string ipAddress = "127.0.0.1";
int port = 54000;
WSAData data;
WORD version = MAKEWORD(2, 2);
int wsResult = WSAStartup(version, &data);
if (wsResult != 0) {
std::cerr << "Can't start Winsock, Err #" << wsResult << std::endl;
return;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
std::cerr << "Can't create socket, Err #" << WSAGetLastError() << std::endl;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
int connResult = connect(sock, (sockaddr *)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR) {
std::cerr << "Can't connect to server, Err #" << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return;
}
char buf[4096];
do {
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0) {
std::cout << "SERVER> " << std::string(buf, 0, bytesReceived) << std::endl;
}
} while (true);
closesocket(sock);
WSACleanup();
}
Это код сервера, который должен работать с несколькими клиентами:
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
void main()
{
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
std::cerr << "Can't Initialize winsock! Quitting" << std::endl;
return;
}
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
std::cerr << "Can't create a socket! Quitting" << std::endl;
return;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listening, (sockaddr*)&hint, sizeof(hint));
listen(listening, SOMAXCONN);
fd_set master;
FD_ZERO(&master);
FD_SET(listening, &master);
while (true)
{
fd_set copy = master;
int socketCount = select(0, ©, nullptr, nullptr, nullptr);
for (int i = 0; i < socketCount; i++)
{
SOCKET sock = copy.fd_array[i];
if (sock == listening)
{
SOCKET client = accept(listening, nullptr, nullptr);
FD_SET(client, &master);
std::string joinMsg = "Client joined\r\n";
send(client, joinMsg.c_str(), joinMsg.size() + 1, 0);
}
else
{
char buf[4096];
ZeroMemory(buf, 4096);
int bytesIn = recv(sock, buf, 4096, 0);
if (bytesIn <= 0)
{
closesocket(sock);
FD_CLR(sock, &master);
}
else
{
for (int i = 0; i < master.fd_count; i++)
{
SOCKET outSock = master.fd_array[i];
if (outSock != listening && outSock != sock)
{
send(outSock, buf, bytesIn, 0);
}
}
}
}
}
}
WSACleanup();
system("pause");
}
Может кто-нибудь сказать мне, что я пропустил?Я уже провел два дня, выясняя, что здесь не так.