求教高手》》
以前沒怎么開發過socket程式,也沒怎么開發過控制臺程式,現在同時涉足兩個不熟悉的領域。
我這個程式,服務端和客戶端都是我寫,客戶端向服務端申請資料,服務端收到請求后往往要等一段時間才回復。因此我用阻塞式,在客戶端和服務端都設定了發送和接收的超時。
70%的概率程式是按我的預期運行的,客戶端請求->服務端收到后,有時候有資料反饋,有時沒資料反饋->客戶端收到資料進入下一次請求回圈;如果收不到,超時回傳,進入下一次請求回圈。
可是有時候就不知道卡在哪里不動了,但是這個時候,如果用滑鼠選中控制臺上面的一些輸出文字資訊,然后點下右鍵,程式就又能繼續運行了,不理解,我這是缺了哪塊知識點了?
為了方便看下面的程式有刪減
客戶端是這么寫的:
SOCKET sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sck == INVALID_SOCKET)
{
return sck;
}
DWORD TimeOut=1000; //設定發送超時1秒
if(setsockopt(sck , SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
cout << "設定發送超時失敗\n:\\>";
}
TimeOut=6000;//設定接收超時6秒
if(setsockopt(sck , SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
cout << "設定接收超時失敗\n:\\>";
}
服務端是這么寫的:
SOCKADDR_IN addrSrv ;
SOCKET sockSrv = socket(AF_INET , SOCK_STREAM , 0) ;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY) ;
addrSrv.sin_family = AF_INET ;
addrSrv.sin_port = htons(5100) ;
bind(sockSrv , (SOCKADDR*) &addrSrv , sizeof(SOCKADDR)) ;
listen(sockSrv , 1) ;
char msgBuf[256] = {0} ;
SocketDataBin sockData ;
while(waitting)
{
SOCKET sockConn = accept(sockSrv , (SOCKADDR*)&addrClient , &len);
DWORD TimeOut=1000; //設定發送超時1秒
setsockopt(sockSrv , SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut)) ;
TimeOut=1000;//設定接收超時1秒
setsockopt(sockSrv , SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut)) ;
recvsize = recv(sockConn , (char *)&sockData , headsize ,0);
CreateThread(NULL , 0 , tradeThread , sockConn , 0 , NULL) ;
//服務端收到連接后創建新執行緒進行處理,主要是recvsize = recv(sockConn , (char *) &recvData , headsize ,0);
}
uj5u.com熱心網友回復:
在程式的開始加上這兩句:HANDLE handle = GetConsoleWindow();
SetConsoleMode(handle, ENABLE_EXTENDED_FLAGS);
uj5u.com熱心網友回復:
謝謝指點,但是我這個程式還要允許互動命令,不能設定這個模式。我奇怪的是,為什么右鍵能重新激活程式?似乎是socket超時失效了,但進入編輯又重新激活了超時?uj5u.com熱心網友回復:
互動命令不影響,那兩句只是關閉控制臺的“快速編輯模式”
uj5u.com熱心網友回復:
應該是 accept阻塞了,和你右鍵點不點擊沒關系,自己Debug一下,列印一下就知道while回圈卡在哪里了uj5u.com熱心網友回復:
建議用 ioctlsocket FIONBIO 改為異步模式,用 select 模型轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/277881.html
標籤:網絡編程