2015-06-18 74 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,但僅此而已,這意味着客戶端將嘗試接受一些東西,還沒有被髮送,直到它接收到什麼會永遠阻塞。

哦,你在服務器中的內存泄漏,您分配內存的名稱(你只明確,但實際上並沒有設置任何東西),但你從來沒有在任何地方釋放內存。無論如何不需要動態分配。

相關問題