Socket出问题了. ( 积分: 100 )

  • 主题发起人 主题发起人 kk2000
  • 开始时间 开始时间
K

kk2000

Unregistered / Unconfirmed
GUEST, unregistred user!
HosServerClientSocket.Socket.SendBuf(PPack^, PacketSize) = SOCKET_ERROR

经常返回 SOCKET_ERROR 是不是网络断开造成的.
就想问大家是什么原因造成的
 
服务器链接断开
 
WSAGetLastError
 
Lock;
try
Result := 0;
if not FConnected then Exit;
Result := send(FSocket, Buf, Count, 0);
if Result = SOCKET_ERROR then
begin
ErrorCode := WSAGetLastError;
if (ErrorCode <> WSAEWOULDBLOCK) then
begin
Error(Self, eeSend, ErrorCode);
Disconnect(FSocket);
if ErrorCode <> 0 then
raise ESocketError.CreateResFmt(@sWindowsSocketError,
[SysErrorMessage(ErrorCode), ErrorCode, 'send']);
end;
end;
finally
Unlock;
end;
//从这段代码来看不一定就是与服务器链接断开吧
//WSAEWOULDBLOCK 这个是什么意思??
 
我以前没有使用心跳测试! 看来我现在必须使用了.
 
如果WSAGetLastError返回WSAEWOULDBLOCK,说明操作没有立刻完成,可以稍后重试,不是致命错误
 
然而,最不容易被初学Socket编程的人理解的,也是本文最要提醒的一点是,客户方在使用CAsyncSocket::Connect()时,往往返回一个WSAEWOULDBLOCK的错误(其它的某些函数调用也如此),实际上这不应该算作一个错误,它是Socket提醒我们,由于你使用了非阻塞Socket方式,所以(连接)操作需要时间,不能瞬间建立。既然如此,我们可以等待呀,等它连接成功为止,于是许多程序员就在调用Connect()之后,Sleep(0),然后不停地用WSAGetLastError()或者CAsyncSocket::GetLastError()查看Socket返回的错误,直到返回成功为止。这是一种错误的做法,断言,你不能达到预期目的。事实上,我们可以在Connect()调用之后等待CAsyncSocket::OnConnect()事件被触发,CAsyncSocket::OnConnect()是要表明Socket要么连接成功了,要么连接彻底失败了。至此,我们在CAsyncSocket::OnConnect()被调用之后就知道是否Socket连接成功了,还是失败了。
类似的,Send()如果返回WSAEWOULDBLOCK错误,我们在OnSend()处等待,Receive()如果返回WSAEWOULDBLOCK错误,我们在OnReceive()处等待,以此类推。

//网上找到的供大家学习学习
 
會出現 10035 WSAEWOULDBLOCK, 代表這個應用程式將 socket 經由
ioctlsocket() 或 WSAAsyncSelect() 函式, 設定為 non-blocking 狀態;
而在程式中呼叫到 accept(), connect(), recv(), send() 等 blocking
函式, 可是目前事件未完成或條件不成立, 原本程式應該會 block 在這個
呼叫, 但由於先前已將 socket 設為 non-blocking 了, 所以我們並不會被
block 住, 函式呼叫會馬上 return, 這時系統給我們的錯誤就是 10035
WSAEWOULDBLOCK.
=======================================================================
呼叫 send() 或 sendto() 傳送資料時,系統告知錯誤,且錯誤碼為
10035 WSAEWOULDBLOCK.(呼叫 WSAGetLastError() 可得知這項錯誤),
這時表示 output buffer 已經滿了,無法再寫入任何資料(此時即令呼叫
再多次的 send() 也都一定失敗);一旦系統將部份資料成功送抵對方,
空出 output buffer 後,便會送一個 FD_WRITE 給使用者,告知可繼續
傳送資料了。換句話說,讀者在呼叫 send() 傳送資料時,只要不是返回
錯誤 10035 的話,便可一直繼續呼叫 send() 來傳送資料;一旦 send()
回返錯誤 10035,那麼便不要再呼叫 send() 傳送資料,而需等收到
FD_WRITE 後,再繼續傳送資料。
 
如果说是在non-blocking 下,发送缓冲满了造成发送返回 WSAEWOULDBLOCK, 那么再多次的 send() 也都一定失敗. 我的情况真的就是这种情况.
==============================================================
如果在发生发送缓冲满了, 网络也断了. 我把套接也关闭了. 这个关闭了的套接会把他的发送缓冲一起释放吗? 如果不释放该如何释放. 我真的担心这种情况发生啊.
 
这种情况一般都是服务器断开了连接!
 
多人接受答案了。
 
后退
顶部