2016-01-26 74 views
0

我正試圖使用​​套接字編程實現簡單的聊天,其中「輸入」鍵將響應從客戶端發送到服務器,反之亦然。下面的代碼按照預期使用特殊字符(如'*')作爲緩衝區,但是當我嘗試使用'\ n'時,不會發送消息。我必須錯誤地執行「輸入」部分。有關如何解決此問題的任何想法?Socket編程簡單聊天C++

服務器:

#include <iostream> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <unistd.h> 

using namespace std; 

int main() 
{ 

    int client, server; 
    int portNum = 1500; 
    bool isExit = false; 
    int bufsize = 1024; 
    char buffer[bufsize]; 

    struct sockaddr_in server_addr; 
    socklen_t size; 

    client = socket(AF_INET, SOCK_STREAM, 0); 

    if (client < 0) 
    { 
     cout << "\nError establishing socket..." << endl; 
     exit(1); 
    } 

    cout << "\n=> Socket server has been created..." << endl; 

    server_addr.sin_family = AF_INET; 
    server_addr.sin_addr.s_addr = htons(INADDR_ANY); 
    server_addr.sin_port = htons(portNum); 


    if ((bind(client, (struct sockaddr*)&server_addr,sizeof(server_addr))) < 0) 
    { 
     cout << "=> Error binding connection, the socket has already been established..." << endl; 
     return -1; 
    } 


    size = sizeof(server_addr); 
    cout << "=> Looking for clients..." << endl; 

    listen(client, 1); 


    int clientCount = 1; 
    server = accept(client,(struct sockaddr *)&server_addr,&size); 

    // first check if it is valid or not 
    if (server < 0) 
     cout << "=> Error on accepting..." << endl; 

    while (server > 0) 
    { 
     strcpy(buffer, "=> Server connected...\n"); 
     send(server, buffer, bufsize, 0); 
     cout << "=> Connected with the client #" << clientCount << ", you are good to go..." << endl; 
     cout << "\n=> Enter # to end the connection\n" << endl; 

     cout << "Client: "; 
     do { 
      recv(server, buffer, bufsize, 0); 
      cout << buffer << " "; 
      if (*buffer == '#') { 
       *buffer = '\n'; 
       isExit = true; 
      } 
     } while (*buffer != '\n'); 

     do { 
      cout << "\nServer: "; 
      do { 
       cin >> buffer; 
       send(server, buffer, bufsize, 0); 
       if (*buffer == '#') { 
        send(server, buffer, bufsize, 0); 
        *buffer = '\n'; 
        isExit = true; 
       } 
      } while (*buffer != '\n'); 

      cout << "Client: "; 
      do { 
       recv(server, buffer, bufsize, 0); 
       cout << buffer << " "; 
       if (*buffer == '#') { 
        *buffer = '\n'; 
        isExit = true; 
       } 
      } while (*buffer != '\n'); 
     } while (!isExit); 

     cout << "\n\n=> Connection terminated with IP " << inet_ntoa(server_addr.sin_addr); 
     close(server); 
     cout << "\nGoodbye..." << endl; 
     isExit = false; 
     exit(1); 
    } 

    close(client); 
    return 0; 
} 

客戶:

#include <iostream> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <netdb.h> 

using namespace std; 

int main() 
{ 

    int client; 
    int portNum = 1500; // NOTE that the port number is same for both client and server 
    bool isExit = false; 
    int bufsize = 1024; 
    char buffer[bufsize]; 
    char* ip = "192.168.0.8"; 

    struct sockaddr_in server_addr; 

    client = socket(AF_INET, SOCK_STREAM, 0); 

    if (client < 0) 
    { 
     cout << "\nError establishing socket..." << endl; 
     exit(1); 
    } 


    cout << "\n=> Socket client has been created..." << endl; 

    server_addr.sin_family = AF_INET; 
    server_addr.sin_port = htons(portNum); 

    if (connect(client,(struct sockaddr *)&server_addr, sizeof(server_addr)) == 0) 
     cout << "=> Connection to the server port number: " << portNum << endl; 


    cout << "=> Awaiting confirmation from the server..." << endl; //line 40 
    recv(client, buffer, bufsize, 0); 
    cout << "=> Connection confirmed, you are good to go..."; 

    cout << "\n\n=> Enter # to end the connection\n" << endl; 

    do { 
     cout << "Client: "; 
     do { 
      cin >> buffer; 
      send(client, buffer, bufsize, 0); 
      if (*buffer == '#') { 
       send(client, buffer, bufsize, 0); 
       *buffer = '\n'; 
       isExit = true; 
      } 
     } while (*buffer != '\n'); 

     cout << "Server: "; 
     do { 
      recv(client, buffer, bufsize, 0); 
      cout << buffer << " "; 
      if (*buffer == '#') { 
       *buffer = '\n'; 
       isExit = true; 
      } 

     } while (*buffer != '\n'); 
     cout << endl; 

    } while (!isExit); 

    cout << "\n=> Connection terminated.\nGoodbye...\n"; 

    close(client); 
    return 0; 
} 

編輯:我做了下面的回答中引用的變化,我仍然沒有得到預期的結果。

這是當我運行服務器和客戶端會發生什麼: enter image description here

當我按下輸入信息不被髮送到服務器。但是,當我使用「buffer ='*'」運行相同的代碼時,它按預期工作。

+1

至少檢查send和recv的返回值。此外,你正在發送你的整個緩衝區,即使當它大部分都是垃圾時,我認爲這些作品是有價值的,但有點古怪。 – hyde

+0

我剛編譯並運行了最近的代碼(如此評論),併發送/接收數據。你的問題是一個應用程序邏輯錯誤,而不是技術誤用套接字API。你試圖達到什麼樣的行爲?當你從客戶端發送時,你是否期望它立即在服務器上回顯,反之亦然? –

回答

2

我不確定你的代碼應該做什麼。

*buffer == '\n'; 

這是你的錯嗎?

它位於服務器代碼:

 cout << "Client: "; 
     do { 
      recv(server, buffer, bufsize, 0); 
      cout << buffer << " "; 
      if (*buffer == '#') { 
       *buffer == '\n'; 
       isExit = true; 
      } 
     } while (*buffer != '\n'); 

我想你的意思是寫:

 cout << "Client: "; 
     do { 
      recv(server, buffer, bufsize, 0); 
      cout << buffer << " "; 
      if (*buffer == '#') { 
       *buffer = '\n'; 
       isExit = true; 
      } 
     } while (*buffer != '\n'); 

看看測試驅動開發的話題。

+0

謝謝你的迴應!我做了這個改變,並在上面添加了關於我遇到的問題的更多細節。該消息沒有正確傳輸到服務器。 –

1

@Johannes已經確定了可能的錯誤(這是一個太常見的錯誤!),這是您正在見證的行爲的罪魁禍首,但您肯定需要傾聽您的編譯器。當我編譯你的服務器源鏗鏘(在CentOS 3.4.2 6)使所有的警告,我得到下面的輸出:

$鐺-Wall -lstdC++ server.cpp

server.cpp:93:29: warning: equality comparison result unused [-Wunused-comparison] 
        *buffer == '\n'; 
        ~~~~~~~~^~~~~~~ 
server.cpp:93:29: note: use '=' to turn this equality comparison into an assignment 
        *buffer == '\n'; 
          ^~ 
          = 
1 warning generated. 

$鐺-Wall -lstdC++ client.cpp

client.cpp:21:16: warning: conversion from string literal to 'char *' is deprecated [-Wc++11-compat-deprecated-writable-strings] 
    char* ip = "192.168.0.8"; 
      ^
client.cpp:21:11: warning: unused variable 'ip' [-Wunused-variable] 
    char* ip = "192.168.0.8"; 
     ^
2 warnings generated. 

您還可以使用任意數量的靜態分析工具(快速搜索給我this wiki)來提高代碼質量的機智最小的努力。

+0

我做了這個改變(見上文),我仍然沒有得到預期的結果。 –

+0

您需要檢查網絡呼叫的返回值以查看其失敗的位置。是否有可能應用程序被本地防火牆阻止? –

+1

爲編譯器添加'-Wextra'警告標誌(* clang *或* gcc *)也不錯。 – hyde