sko*_*ima 7 c# sockets timeout compact-framework windows-mobile
在完整的.Net Framework上,我使用以下代码:
socket.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, readTimeout);
socket.SetSocketOption(
SocketOptionLevel.Socket, SocketOptionName.SendTimeout, writeTimeout);
Run Code Online (Sandbox Code Playgroud)
但是,Windows Mobile不支持此操作并抛出异常.
我目前正在测试此解决方案以实现超时.
有谁知道更好的方法?如果可能的话,我想避免产生多个线程,毕竟这是一个嵌入式设备.
此代码有效,可在预期时提高超时(它是我在问题中链接的示例的修改版本):
// copied from Mono, because CF lacks this enum
enum SocketError
{
IOPending = 997,
NoBufferSpaceAvailable = 10055,
TimedOut = 10060,
WouldBlock = 10035
}
// milliseconds
int receiveTimeout = 20000;
int sendTimeout = 20000;
public override int Read(byte[] buffer, int offset, int size)
{
int startTickCount = Environment.TickCount;
int received = 0;
do
{
List<Socket> sock = new List<Socket>(new Socket[] {socket});
Socket.Select(sock, null, null, receiveTimeout*1000 + 1);
if (Environment.TickCount > startTickCount + receiveTimeout)
throw new SocketException((int) SocketError.TimedOut);
try
{
received += socket.Receive(buffer, offset + received,
size - received, SocketFlags.None);
}
catch (SocketException ex)
{
if (ex.ErrorCode == (int) SocketError.WouldBlock ||
ex.ErrorCode == (int) SocketError.IOPending ||
ex.ErrorCode == (int) SocketError.NoBufferSpaceAvailable)
{
// socket buffer is probably empty, wait and try again
Thread.Sleep(30);
}
else
throw; // any serious error occurr
}
} while (received < size);
return received;
}
public override void Write(byte[] buffer, int offset, int size)
{
int startTickCount = Environment.TickCount;
int sent = 0;
do
{
List<Socket> sock = new List<Socket>(new Socket[] {socket});
Socket.Select(null, sock, null, sendTimeout*1000 + 1);
if (Environment.TickCount > startTickCount + sendTimeout)
throw new SocketException((int) SocketError.TimedOut);
try
{
sent += socket.Send(buffer, offset + sent,
size - sent, SocketFlags.None);
}
catch (SocketException ex)
{
if (ex.ErrorCode == (int) SocketError.WouldBlock ||
ex.ErrorCode == (int) SocketError.IOPending ||
ex.ErrorCode == (int) SocketError.NoBufferSpaceAvailable)
{
// socket buffer is probably full, wait and try again
Thread.Sleep(30);
}
else
throw; // any serious error occurr
}
} while (sent < size);
}
Run Code Online (Sandbox Code Playgroud)
我发现的例子中缺少的关键因素是Socket.Select(IList checkRead, IList checkWrite, IList checkError, int microSeconds).请记住,此方法可能会修改传递给它的列表(这就是我的代码每次都创建一个新代码的原因),并以微秒而不是毫秒来度量时间.并记住使用Environment.TickCount(这是一个单调的时间源)而不是DateTime.Now测量时间.
| 归档时间: |
|
| 查看次数: |
3742 次 |
| 最近记录: |