我刚开始使用套接字编程,而我只是试图让客户端通过TCP连接将数据发送到服务器。然后,服务器将数据转发到一个固定客户端,该客户端只是显示它。
我认为这不会太难。在我设置服务器和仅显示已发送数据的客户端后,我使用PuTTY创建了多个客户端,将一些数据发送到服务器,一切正常。服务器转发消息,固定客户端显示消息。但是现在我已经编写了那些"发送客户端",我只能让其中一个客户端发送一条消息,之后一切都被"卡住了#34;。没有错误消息或任何内容。一旦我发送第二条消息,控制台就不会提示我给它第三条消息。我只能关闭客户和那个客户。
这里是简单发送数据的客户端的代码:
#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");
}
有人可以告诉我我错过了什么吗?我已经花了两天时间搞清楚,这里有什么问题。