2012-04-13 225 views
0

這是我的情況,我有一個服務器偵聽連接,並且我現在正在編程一個客戶端。客戶端無法從服務器接收任何內容,但它必須每3分鐘發送一次狀態更新。客戶端到服務器連接只發送不接收

我此刻的以下內容:

WSAStartup(0x101,&ws); 
    sock = socket(AF_INET,SOCK_STREAM,0); 
    sa.sin_family = AF_INET; 
    sa.sin_port = htons(PORT_NET); 
    sa.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    connect(sock,(SOCKADDR*)&sa,sizeof(sa)); 
    send(sock,(const char*)buffer,128,NULL); 

我的方法應該如何呢?我可以避免循環recv?

回答

0

這取決於你想要的行爲和你的程序結構。 默認情況下,套接字將阻止任何讀取或寫入操作,這意味着如果您嘗試讓服務器的主線程輪詢連接,則最終會「凍結」3分鐘或直到客戶端關閉連接。

絕對最簡單的功能性溶液(無multithreadding)是設置插座無阻塞,並且在主線程輪詢英寸這聽起來像你想避免這樣做,但。

周圍最明顯的方法是讓一個專用的線程爲每個連接,再加上主監聽套接字。您的服務器偵聽傳入連接併爲其創建的每個流套接字產生一個線程。然後,每個連接線程都會阻塞它的套接字,直到它接收到數據,並自行處理它或將其分流到共享隊列中。 這是一個龐大而複雜的解決方案 - 需要打開和關閉的多個線程,需要保護的共享資源。

另一個選項是設置套接字到非阻塞(下的Win32使用setsockopt的如此設置超時,下* nix中傳遞給它O_NONBLOCK標誌)。這樣,如果沒有可讀取的數據,它將返回控制權。但是這意味着您需要以合理的時間間隔輪詢套接字(「合理」完全取決於您,以及您需要服務器如何快速處理新數據。)

就個人而言,對於您描述的輕量級應用我將使用上面的組合:一個專用線程,每隔幾秒輪詢一個套接字(或一個非阻塞套接字數組),在兩者之間休眠,並簡單地將數據推送到主線程在其間執行的隊列中它是主循環。

有很多的方式進入異步程序的混亂,所以它可能是最好的保持它的簡單,並得到它的工作,直到你滿意的控制流。

+0

如果我每次發送內容時關閉連接,並在下次需要發送內容時打開一個新連接,這樣我就可以避免阻塞。聽上去怎麼樣? – 2012-04-13 15:04:49

+0

是的,你可以做到這一點(事實上,如果你只是推動狀態更新,你可能也會如此)。問題在於服務器將在accept()上被阻塞,而不僅僅是在讀取數據時。基本上你的服務器不能保證連接何時發生,因此需要不斷的收聽。你可以設置一個超時(兩端),並依靠雙方知道它們意圖形成連接的時間,但這是一個容易出錯的問題。編輯:但是,如果你的服務器需要做的唯一事情是進程狀態更新,那麼是的,這可以正常工作。 – Bhau 2012-04-13 15:22:54

+0

好吧,我不介意服務器是否在不停地收聽。我最初的問題是我在不關閉連接的情況下調用send(),並且只發送第一個狀態,並且我在類似案例中閱讀了這裏(http://stackoverflow.com/q/8347107/777510)我需要調用recv併發送一個循環來避免這種情況,我所要求的是如果我可以通過發送和關閉連接來避免該循環。所以我應該罰款嗎? – 2012-04-13 15:42:46

相關問題