2012-01-16 60 views
1

我通過套接字發送一些數據,但我需要設置超時。
我使用的是這樣的:選擇與數據套接字迷失

fd_set rfds; 
struct timeval tv; 
int retval; 
/* Watch stdin (fd 0) to see when it has input. */ 
FD_ZERO(&rfds); 
FD_SET(sockDesc, &rfds); 
/* Wait up to five seconds. */ 
tv.tv_sec = 5; 
tv.tv_usec = 0; 
retval = select(sockDesc + 1, &rfds, NULL, NULL, &tv); 
if(rtn = ::recv(sockDesc, (raw_type*) buffer, bufferLen, 0)) < 0){ 
throw SocketException("error", true); 
} 
return rtn; 

所以。
根據我返回的數據類型,我需要實現超時與否。
如果我只是發送文本數據,我不需要,如果我發送一個文件,我需要...
或多或少地解釋我通過套接字發送一些數據並在另一端進行處理。
所以,如果我發送一個焦油:

while(readtar){ 

    senddata 
    get processed data 
} 

但有時發送的數據僅僅是頭,所以當它不是對方的過程數據需要返回數據,並在插座上讀取停止。
舉例說明: cat file.tar | myprogram -c「tar -zvt」

所以它不會返回任何內容,直到收到足夠的數據才能返回文件的名稱。

,如果我只是發送一個文件,並返回「貓」我沒有這個問題
回聲「asjdoiajdlaijdkasdjlkas」 | myprogram -c「cat」

cat HUGEFILE.tar | myprogram -c「cat」| tar -zvt
在這種情況下,它做同樣的事情,但不是在服務器端......所以它不爲我工作。

現在....如果我只是使用recv沒有選擇,當我使用貓返回數據它的工作......沒有問題。
但如果我執行選擇的數據來混亂。

WITHOUT SELECT

send "command line text temp test" 
recv "command line text temp test" 

send "command line text temp test" 
recv "commmand lin/ˆ 
1k5d99ck" 

它只是說明發生了什麼

客戶循環:

while(size = read(fileno(stdin), thebuffer, 10000)){ 
    sock->send(thebuffer, size); // if this data is not enough the other side never sends the data back 
    sock->recv //receive data 
} 

在OTH呃邊我

if(pid == 0){ 
//stuffs closes, dup2 
execlp("bash", "bash", "-c", "run.c_str(), NULL); // if i use one tar -zvt i need a bunch of data to generate the return 
    } 
else 
while(size = read(fout[0], buffer, 10000) > 0)){ 
    sock->send(buffer, size); 
} 

所以..如果要是讀任何東西都還是在標準輸入側,如果execlp發送終止我可以解決這個問題發送的數據是不夠的,產生於 如果我可以檢查

回答

4

這聽起來像你期待您的TCP recv()以特定大小的塊返回數據給您...但是,TCP recv()不以這種方式工作。 TCP是基於流的,所以recv()返回的字節數可以在1(或者如果使用非阻塞I/O時爲0)和傳入的緩衝區大小之間任意變化。然後由您決定接收代碼以根據需要循環以再次重新連接所接收的數據。

此外,它看起來像你試圖打印出未終止的ASCII字符串 - 這將解釋你的第二個recv()例子結束時的垃圾字符。 (也就是說,如果要將接收到的數據字節打印爲字符串,請務必在最後接收的字節後面放置一個NUL/0字節; recv()不會爲您執行該操作)

+0

如果我不使用選擇所有的數據來確定。如果我發送大文本,一切都好。 – Lefsler 2012-01-16 17:51:52

+0

問題是當我需要等待數據,因爲它沒有發送好的這個循環。對於我來說,數據可以以任何大小進行傳輸,但是如果在同一個循環中,我發送它不發送數據,我有問題,因爲recv需要接收數據。 – Lefsler 2012-01-16 17:53:07

+0

「或0,如果你使用非阻塞I/O」 - 實際上,如果非阻塞套接字沒有數據可用(並且errno將是EAGAIN或EWOULDBLOCK),recv將返回-1。 0僅返回以指示遠端已經關閉或關閉其結束。 – selbie 2012-01-16 20:30:32