我制作了两个C ++文件,一个用于服务器,另一个用于客户端。正如您在下面的代码中看到的那样,我想向客户端显示它们已连接,以及它们的ID,但是当我尝试连接时,它会正确地清除控制台,但是不会显示它们的ID 。我注意到当我关闭服务器并且客户端仍在运行时,客户端会显示ID。不太确定问题是什么,将等待你的回复!在此先感谢,这是代码。
服务器:
// First, we'll include all the required files
#include <winsock.h>
#include <iostream>
#include <Windows.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib") // Require this lib for winsock
SOCKADDR_IN addr; // This structure saves the address and ports of the server
int addrlen = sizeof(addr); // This saves the length of the address
int Counter; // Counts how many connected clients there are
SOCKET sConnect; // Socket for incoming connections
SOCKET sListen; // Socket for listening
SOCKET *Connections; // Socket for all the connections
// Init the winsock library
int InitWinSock()
{
int Val = 0; // Make a default
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
Val = WSAStartup(DllVersion, &wsaData); // Initialise winsock
return 0;
}
int main()
{
system("color 0a"); // Change the console color to black-green
cout << "Server Started." << endl;
// Winsock Init
int Val = InitWinSock();
if(Val != 0)
{
// If WinSock Init fails, display an error
MessageBoxA(NULL, "Error while starting WinSock!", "Error", MB_OK | MB_ICONERROR);
exit(1); // Stop the procedure
}
Connections = (SOCKET*) calloc(64, sizeof(SOCKET));
// Init the sockets
sListen = socket(AF_INET, SOCK_STREAM, NULL);
sConnect = socket(AF_INET, SOCK_STREAM, NULL);
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Server address, 127.0.0.1 is localhost
addr.sin_port = htons(2222); // Server port
addr.sin_family = AF_INET; // This is the type of connection
bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); // Bind server to address and port
listen(sListen, 64); // Listen for any incoming connections
while(true)
{
if(sConnect = accept(sListen, (SOCKADDR*)&addr, &addrlen))
{
Connections[Counter] = sConnect;
char *Name = new char[64]; // The name of the client
ZeroMemory(Name, 64); // We make the char empty
sprintf(Name, "%i", Counter);
send(Connections[Counter], Name, 64, NULL); // We send the ID to the client
cout << "New Connection!" << endl;
Counter ++; // Increase the amount of clients
} // end if accept the connection
Sleep(50); // Wait 50 milliseconds
} // end while search for connections
}
客户端:
#include <iostream>
#include <winsock.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
SOCKET sConnect; // The connection socket
SOCKADDR_IN addr; // The server adress
int Startup_WinSock()
{
WSADATA wsaData;
WORD DllVersion = MAKEWORD(2, 1);
int Val = WSAStartup(DllVersion, &wsaData);
return Val;
}
int main()
{
system("color 0a");
int Val = Startup_WinSock();
if(Val != 0)
{
cout << "Can't Startup WinSock!" << endl; // Display error
exit(1);
}
sConnect = socket(AF_INET, SOCK_STREAM, NULL);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(2222);
addr.sin_family = AF_INET;
cout << "Please press [ENTER]" << endl;
cin.get();
Val = connect(sConnect, (SOCKADDR*)&addr, sizeof(addr)); // Connect with the server
if(Val != 0)
{
cout << "Can't reach the server!" << endl;
main (); // Try again
}
else
{
system("cls"); // Clear the screen
int ID;
char *nID = new char[64]; // Client's ID
char *hello = new char[64]; // Message from the server
ZeroMemory(nID, 64);
ZeroMemory(hello, 64);
recv(sConnect, nID, 64, NULL); // Receive ID from server
recv(sConnect, hello, 64, NULL); // Receive message from the server
ID = atoi(nID); // Cast to an int
cout << hello << endl;
cout << "Your ID: " << ID << endl;
cin.get();
}
return 0;
}
答案 0 :(得分:3)
recv(sConnect, nID, 64, NULL); // Receive ID from server
recv(sConnect, hello, 64, NULL); // Receive message from the server
首先,您在此处没有错误检查。您需要在整个程序中添加错误检查,否则将无法进行故障排除。
其次,这里没有消息处理。如果第一个recv
获得3个字节会发生什么?您最终会将其余ID读入hello字段。
第三,你不发送任何消息。因此第二个recv
将等待读取尝试失败,即服务器终止时。
答案 1 :(得分:1)
在服务器中,您只发送ID,但仅此而已,这意味着客户端将尝试接收尚未发送的内容,并在收到任何内容之前永久阻止。
哦,你在服务器上有内存泄漏,你为名称分配内存(你只清楚,但实际上没有设置任何东西),但你永远不会释放内存。无论如何都不需要动态分配。