2015-06-18 71 views
-1

我做了两个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

你有一个调试器,使用它。 –

+0

切勿以递归方式调用'main',请使用循环! –

+0

谢谢@JoachimPileborg,总是欣赏正面的反馈! – Jono

回答

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将等待,直到读取尝试失败,即服务器被终止。

+0

谢谢,对不起。我从来没有做过很长时间的C++。 – Jono

+1

尽管最大的问题是你假装TCP是一个消息协议并试图发送和接收消息。但TCP不是一种消息协议,它是一种字节流协议。如果你想要消息,你必须实现它们。你没有。代码发送消息在哪里?接收消息的代码在哪里? –

1

在服务器只发送的ID,但仅此而已,这意味着客户端将尝试接受一些东西,还没有被发送,直到它接收到什么会永远阻塞。

哦,你在服务器中的内存泄漏,您分配内存的名称(你只明确,但实际上并没有设置任何东西),但你从来没有在任何地方释放内存。无论如何不需要动态分配。

相关问题