还是socket通信超时问题(100分)

thunderwolf 2009-05-21 03:56:58


private void sendrfiddata()
{
tcpClient2.ReceiveTimeout = 1000;
senddata.WriteLine("entrybalance," + "京A12345");
senddata.Flush();
byte[] Data = new Byte[400];
Int32 bytes;
while (true)
{
try
{
bytes = ns.Read(Data, 0, Data.Length);
string receiveData = Encoding.Default.GetString(Data, 0, bytes); break;
}

catch(Exception ex)
{
//do nothing
}
}
}


程序意思是:不停的接受数据,如果服务器端20秒返回数据,我也要等到20秒才能收到,也才能做下一步工作吧!
但是我不希望这样,我希望1秒钟没有返回数据,我就放弃这条数据。
经过我测试的结果显示,放弃的这条数据一直保存在socket中通道中,等有下一条数据超时,客户端接受通道中已有的数据,所以ReceiveTimeout 属性就没有作用了!
事实上是不是我分析的这样啊!有没有方法可以把socket通道中的数据先清除掉呢! 或者说同步通信的这种方式根本就行不通。一定要等接收到数据才能进行下一步
代码。
...全文
181 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
CGabriel 2009-05-21
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 thunderwolf 的回复:]
to: CGabriel


如果我在服务器上判断的话,那从服务器传输到到客户端,这不是又需要一段时间呢?如果在这时发生超时了。那这个判断超时不是就不全面了
[/Quote]

如果是同步通信,Send 方法执行完毕
如果是异步通信, EndSend 回调开始

上面两个时间非常接近客户端收到数据的时间
服务器是没有办法极度精确地知道客户端收到封包的时间的,除非你让客户端自己告诉你....不过那样又多一个封包, 你也是不会干的,笑.

如果你仅是关心客户端的处理时间是否超过一秒的话, 可以在客户端发回服务端的封包中加上客户端自己的开始处理时间与处理结束时间。服务端比较一下这两个时间就可以,或者直接返回处理的毫秒数就是了 不用在网络接收上面考虑那么多
utopia54 2009-05-21
  • 打赏
  • 举报
回复
UP
bbb332 2009-05-21
  • 打赏
  • 举报
回复
up
cnzdgs 2009-05-21
  • 打赏
  • 举报
回复
超时后断开连接。
liumj2001 2009-05-21
  • 打赏
  • 举报
回复
87708849

加群,讨论通讯技术。
thunderwolf 2009-05-21
  • 打赏
  • 举报
回复
to: CGabriel

你是搞反了顺序。
是否超时不应该从客户端提供的数据上判断了, 而是应该又服务端主动判断。

实际上根本还是一个数据辨别的问题,可以再服务器发出命令的时候,带有一个特有的标志(通常是一个枚举值),要求客户端收到之后返回。
发送之后,服务器会接受全部的数据, 看一秒之内这个标志是否返回了。 要是有返回则操作成功,没有返回,以后就算收到耶丢掉。

如果我在服务器上判断的话,那从服务器传输到到客户端,这不是又需要一段时间呢?如果在这时发生超时了。那这个判断超时不是就不全面了。
CGabriel 2009-05-21
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 thunderwolf 的回复:]
to: CGabriel
如果是先接收的话,那不是要等到20秒后服务器返回数据才行呢!我现在时不能等那么长的时间,1秒钟后必须处理
[/Quote]

你是搞反了顺序。

是否超时不应该从客户端提供的数据上判断了, 而是应该又服务端主动判断。

实际上根本还是一个数据辨别的问题,可以再服务器发出命令的时候,带有一个特有的标志(通常是一个枚举值),要求客户端收到之后返回。
发送之后,服务器会接受全部的数据, 看一秒之内这个标志是否返回了。 要是有返回则操作成功,没有返回,以后就算收到耶丢掉。
thunderwolf 2009-05-21
  • 打赏
  • 举报
回复
那用同步通信的方式就没有解决的方法了吗
zhushoudong 2009-05-21
  • 打赏
  • 举报
回复
如果先接受了的话 超时还是要等的哦
zzxap 2009-05-21
  • 打赏
  • 举报
回复
[code=C#]
//连接超时
//--------------------------------------------------------------------------
//设置为非阻塞方式连接
unsigned long ul = 1;
int ret = ioctlsocket(m_sSocket, FIONBIO, (unsigned long*)&ul);
if(ret == SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(m_sSocket);
m_sSocket = NULL;
return FALSE;
}
struct timeval timeout ; // 超时结构
fd_set r;

FD_ZERO(&r);
FD_SET(m_sSocket, &r);
timeout.tv_sec = iTimeout; // 连接超时设置
timeout.tv_usec =0;

connect(m_sSocket,(LPSOCKADDR)&server,sizeof(SOCKADDR));
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
err = WSAGetLastError();
closesocket(m_sSocket);
m_sSocket = NULL;
return FALSE;
}

//设回阻塞模式
ul = 0 ;
ret = ioctlsocket(m_sSocket, FIONBIO, (unsigned long*)&ul);
//--------------------------------------------------------------------------


//接收超时
//-------------------------------------------
//接收超时设置
struct timeval outtime ; // 超时结构

FD_SET fdr = {1, m_sSocket};
outtime.tv_sec = timeout;
outtime.tv_usec =0;
int nSelectRet;
//------------------------------------------------------------
//网络只认单字节串,而EVC里多字节;发送的UNICODE串转换成单字节串
UINT nLen = len * 2;
char *pByte = new char[nLen+1];
memset(pByte, 0, nLen+1);
WideCharToMultiByte(CP_ACP, NULL, buf, wcslen(buf),pByte, nLen, NULL, NULL);
int nRet;

nSelectRet=::select(0, &fdr, NULL, NULL, &outtime); //检查可读状态
if(SOCKET_ERROR==nSelectRet)
{
err = WSAGetLastError();
closesocket(m_sSocket);
m_sSocket = NULL;
return -1;
}
if(nSelectRet==0) //超时发生,无可读数据
{
AfxMessageBox(L"接收超时");
err = WSAGetLastError();
closesocket(m_sSocket);
m_sSocket = NULL;
return -1;
}
else
{
//接收数据
nRet = recv(m_sSocket, pByte, nLen, 0);
if(nRet == SOCKET_ERROR)
{
err = WSAGetLastError();
}
}

//-------------------------------------------

MultiByteToWideChar(CP_ACP, NULL, pByte, nLen, buf, len);
delete [] pByte;
pByte = NULL;

//---------------------------------------------------------------------
[/CODE]
thunderwolf 2009-05-21
  • 打赏
  • 举报
回复
是不是同步通信的这种方式做不到这点,1秒钟数据没有返回。不能做任何操作呢?
thunderwolf 2009-05-21
  • 打赏
  • 举报
回复
to: CGabriel
如果是先接收的话,那不是要等到20秒后服务器返回数据才行呢!我现在时不能等那么长的时间,1秒钟后必须处理
CGabriel 2009-05-21
  • 打赏
  • 举报
回复
要清空容易, 对这缓冲区大小, 一次过读出来, 然后丢掉就是
我不懂电脑 2009-05-21
  • 打赏
  • 举报
回复
清除的方法就是接收后丢弃不处理。
CGabriel 2009-05-21
  • 打赏
  • 举报
回复
建议不要在 Socket 上面清空

可以把消息先收下, 在收下的同时在上面打个时间戳, 如果时间戳超过了 1 秒就不处理它
thunderwolf 2009-05-21
  • 打赏
  • 举报
回复
这个怎么进行清除啊!一直找清除的方法没有找到?
hecker728 2009-05-21
  • 打赏
  • 举报
回复
如果超时放弃这条数据的同时,进行清除

110,572

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧