2011-05-10 68 views
1

我正在測試我的TCP回顯服務器,用Telnet,我可以看到客戶端連接到服務器併發送一個字符,並作爲回報,服務器返回一個字符串給客戶端。C/LF條件檢查C

現在我的問題是通過在無限循環中使用此recv()我只能接收一個字符(即使客戶端傾向於發送字符串)。

這就是我正在做的從客戶端接收數據報

TCP SERVER

while(1) 
{ 
    socket = accept(server_socket, (struct sockaddr *)&client_address, (socklen_t)&client_length); 

    recv(socket, recv_buffer, sizeof(recv_buffer), 0); 
    printf("Received string from client is %s", recv_buffer); 

    /*then I send my string to the client*/ 
    send(socket, send_buffer, sizeof(send_buffer), 0); 
} 

這裏是我的問題,我的recv()函數讀取,即使客戶想只有一個字符發送整個字符串。有沒有辦法讓recv()例程在接收到來自客戶端的所有字符之前等待,然後向客戶端發送響應。

任何建議,將不勝感激

問候

+0

接收代碼在哪裏? – wallyk 2011-05-10 07:45:15

+1

作爲一個側面問題...值得注意的是,Telnet是一個終端客戶端,所以它不僅會傳輸你輸入的字符串到你的服務器,所以如果你得到一些可能乍一看似乎是垃圾的控制代碼,請不要驚訝... – forsvarir 2011-05-10 07:55:47

+0

我的問題是,即使客戶端向我發送一個完整的字符串,即我手動在telnet客戶端上鍵入,我也只收到一個字符。只要我輸入一個字母,它就會被ma服務器接收到,我的服務器發送一個可以在telnet的終端輸出中看到的文本。 – Devb 2011-05-10 10:58:49

回答

1

好吧,你正在做的事情是錯誤的。看看recv定義:

int recv(int s, void *buf, size_t len, int flags); 

所以臨危len量的字節。您通過了sizeof(recv_buffer)作爲len參數。現在我猜recv_buffer被定義爲char*。獲取指針的sizeof意味着您將獲得存儲該指針所需的字節數,而不是指向的內存。

做這樣的事情,而不是:

const int buf_len = 100; 
char recv_buffer[buf_len]; 

recv(socket, recv_buffer, buf_len, 0); 
printf("Received string from client is %s", recv_buffer); 
+0

通常不起作用 - 不保證可以通過一次調用recv()來接收字符串。 – 2011-05-10 07:51:49

+0

@unapersson:的確如此,但這個故事複雜化了。問題在於指針的'sizeof'。 – orlp 2011-05-10 07:53:55

+0

我已經厭倦了你的建議,但仍然是它的結果 – Devb 2011-05-10 10:31:23

1

你需要建立你自己接受在一個循環的字符串,使用recv()返回值來找到你實際上有多少個字節了。 TCP/IP不保證可以通過對recv()的一個呼叫接收所有通過一次呼叫發送至send()的數據。您必須檢查您調用的每個套接字函數的返回值,以檢查發送/接收的實際長度以及錯誤。

+0

我檢查了recv()的返回值,它顯示我'1',這意味着只要我收到一個字符我的send()函數喚起併發送一個字符串。 – Devb 2011-05-10 08:36:01

+0

可能是一小段代碼,可以真正澄清這一點。 – Devb 2011-05-10 08:36:31

+0

@Devb你必須保持調用recv,直到你收到你期望的所有字符。 – 2011-05-10 08:37:59

1

你的代碼是一個災難(對於鈍的抱歉,但最好是直的)。

recv()返回實際讀取的字節數。不僅如此,它不會清除緩衝區的前一個內容,並且如果有可用的數據,它將填滿緩衝區的末尾。所有這一切意味着你不能將緩衝區的內容視爲以空字符結尾的字符串。

你需要做的是這樣的:

ssize_t bytesRead = 1; 
char recv_buffer[SOME_SIZE]; 

while (bytesRead > 0) 
{ 
    int bytesRead = recv(socket, recv_buffer, SOME_SIZE, 0); 
    if (bytesRead > 0) 
    { 
     // do something with the bytes. Note you cannot guarantee that the buffer contains a valid C string. 
    }  
} 
if (bytesRead == -1) 
{ 
    // report error from errno 
} 
else 
{ 
    // bytesRead == 0 have reached end of file (i.e. socket closed at other end) 
} 

有沒有辦法讓recv的等待,直到緩衝區返回之前滿。它將等待,直到有一些字節可用,然後返回。這同樣適用於順便發送。你不能假設一個呼叫發送你的所有字節實際上已經發送。你也需要發送循環:

ssize_t totalBytesWritten = 0; 
ssize_t bytesWritten = 0; 
while (bytesWritten >= 0 && totalBytesWritten < bytesToWrite) 
{ 
    bytesWritten = send(socket, sendBuffer + totalBytesWritten, bytesToWrite - totalBytesWritten, 0); 
    if (bytesWritten > 0) 
    { 
     totalBytesWritten += bytesWritten; 
    } 
} 
if (bytesWritten == -1) 
{ 
    // error 
} 
+0

我需要說的是,在遵循你的建議後,我仍然無法獲得所需的輸出,因爲發送它與我的舊代碼一起工作正常。我仍然不知道 – Devb 2011-05-10 09:19:33