c#.net Tcp socket 接收时数据丢失

tanbiao1987 2010-07-12 02:25:29
老问题。
服务器和客户端采用Tcp方式连接。
服务器连续发送几条数据过来,客户端while(true)循环接收
结果只能接收到前面两条数据,后面还有数据接收不到。
服务器端确保没有问题,问题应处在客户端。
找不到问题所在,小弟分数不多,忘大虾们帮助。。。
代码:

//监听网络
public bool OpenNet(string sPort)
{
processor = new Thread(new ThreadStart(StartListening));//新建监听线程
processor.Priority = ThreadPriority.Normal;
processor.IsBackground = true;
processor.Start();//线程开始
return true;
}
private void StartListening()
{
//获取端口号
string sPort = m_IniFile.IniReadValue("Net", "TcpPort");
int iPort = int.Parse(sPort);
//
m_bListen = false;
//
try
{
m_EndPoint = new IPEndPoint(IPAddress.Any, iPort);//组合将访问主机的IP地址和端口号。
_svrSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//实例化Socket对象。
_svrSock.Bind(m_EndPoint);//绑定将访问的主机。
_svrSock.Listen(50);//开始监听,最大包长50。

//while循环接收
while (true)
{
if (m_bListen == false)
{
accsock = _svrSock.Accept();//接收客户端的服务请求套接字。
}
//
iDataBufLen = (ushort)accsock.Receive(bDataBuf, bDataBuf.Length, 0);
//
if (iDataBufLen > 0)
{
//处理数据
//同时m_bListen被置true
}
}
}
catch (Exception ex)
{
MessageBox.Show("监听异常:" + ex.Message);
return;
}
}

...全文
1176 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
tanbiao1987 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wxm3630478 的回复:]
只有接收端的代码.....没办法看的


服务器连续发送几条数据过来,客户端while(true)循环接收
结果只能接收到前面两条数据,后面还有数据接收不到。


从这2句话看,很有可能是出现的粘包啦.....Tcp如果连续发送数据...最好自己先定义好一个发送接收的规则

http://blog.csdn.net/wxm3630478/archive/2010/05/31/56……
[/Quote]
黑大哥正解,按照你发链接的提示,问题解决,果然是黏包了...
分数不多,照样散分,TKS。。。。
tanbiao1987 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 cgabriel 的回复:]
收是能够收到,但是你的接受程序不知道要收到什么时候终止。或者可能因为什么问题,接受程序停了一下,后面的数据是谁的也就搞不清楚了。

当然,能够编写一个人工智能程序处理另当别论。
[/Quote]
接收程序不中止,因为服务器端指不定什么时候发数据过来,所以循环接收。
如果接收不到数据iDataBufLen = (ushort)accsock.Receive(bDataBuf, bDataBuf.Length, 0);
这里应该会挂起等待吧。。。
接收程序停一下?是不是处理数据的时候出错了,或者其他原因,会导致数据找不到是谁的了?
坐等,谢谢了。。。
CGabriel 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 tanbiao1987 的回复:]

引用 5 楼 wxm3630478 的回复:
http://blog.csdn.net/wxm3630478/archive/2010/05/31/56……

粗略看了你的链接,你所说的规则应该是服务器端发送不确定长度报文时候,应该要添加n个字节的报文头标识报文的长度,以便接收处理。不知理解是否正确???
现在的情况是服务器端发送的数据长度确实是不固定的,通过报文也能确定它每条数据的变长……
[/Quote]

收是能够收到,但是你的接受程序不知道要收到什么时候终止。或者可能因为什么问题,接受程序停了一下,后面的数据是谁的也就搞不清楚了。

当然,能够编写一个人工智能程序处理另当别论。
tanbiao1987 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wxm3630478 的回复:]
http://blog.csdn.net/wxm3630478/archive/2010/05/31/56……
[/Quote]
粗略看了你的链接,你所说的规则应该是服务器端发送不确定长度报文时候,应该要添加n个字节的报文头标识报文的长度,以便接收处理。不知理解是否正确???
现在的情况是服务器端发送的数据长度确实是不固定的,通过报文也能确定它每条数据的变长。
但是无论服务器端发送过来的数据是多长,只要我客户端循环监听,就应该能收到连续发过来的几条数据吧?
不止理解是否有问题,忘赐教。。。
tanbiao1987 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wxm3630478 的回复:]
只有接收端的代码.....没办法看的
[/Quote]
有一个VC写的客户端,能接受到全部的数据,所以认为服务器端没问题。
至于你所说的发送接收规则,不太理解。。。
wxm3630478 2010-07-12
  • 打赏
  • 举报
回复
只有接收端的代码.....没办法看的


服务器连续发送几条数据过来,客户端while(true)循环接收
结果只能接收到前面两条数据,后面还有数据接收不到。



从这2句话看,很有可能是出现的粘包啦.....Tcp如果连续发送数据...最好自己先定义好一个发送接收的规则

http://blog.csdn.net/wxm3630478/archive/2010/05/31/5636446.aspx
tanbiao1987 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zxp8819 的回复:]

Receive(array<Byte>[]()[], Int32, SocketFlags) 使用指定的 SocketFlags,从绑定的 Socket 接收指定字节数的数据,并将数据存入接收缓冲区。

[/Quote]
就是这个,只不过最后一个参数用0代替,貌似相当于SocketFlags.None。测试过,结果一样的,还是只能收到2条数据。是否SocketFalgs要换成其他模式?请教
铛铛 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 tanbiao1987 的回复:]
Socket..::.Receive 方法 接收来自绑定的 Socket 的数据。


重载列表
名称 说明
Receive(IList<(Of <(ArraySegment<(Of <(Byte>)>)>)>)) 从绑定的 Socket 接收数据,将数据存入接收缓冲区列表中。
Receive(array<Byte>[]()[]) 从绑定的 Socket 套接字接收数据,将数据存入接收缓冲区。
Receive(IList<(Of <(ArraySegment<(Of <(Byte>)>)>)>), SocketFlags) 使用指定的 SocketFlags,从绑定的 Socket 接收数据,将数据存入接收缓冲区列表中。
Receive(array<Byte>[]()[], SocketFlags) 使用指定的 SocketFlags,从绑定的 Socket 接收数据,将数据存入接收缓冲区。
Receive(IList<(Of <(ArraySegment<(Of <(Byte>)>)>)>), SocketFlags, SocketError%) 使用指定的 SocketFlags,从绑定的 Socket 接收数据,将数据存入接收缓冲区列表中。
Receive(array<Byte>[]()[], Int32, SocketFlags) 使用指定的 SocketFlags,从绑定的 Socket 接收指定字节数的数据,并将数据存入接收缓冲区。
Receive(array<Byte>[]()[], Int32, Int32, SocketFlags) 使用指定的 SocketFlags,从绑定的 Socket 接收指定的字节数,存入接收缓冲区的指定偏移量位置。
Receive(array<Byte>[]()[], Int32, Int32, SocketFlags, SocketError%) 使用指定的 SocketFlags,从绑定的 Socket 接收数据,将数据存入接收缓冲区。
[/Quote]
貌似没发现Socket.Receive(byte[],int,int)这个重载
tanbiao1987 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zxp8819 的回复:]
引用楼主 tanbiao1987 的回复:
iDataBufLen = (ushort)accsock.Receive(bDataBuf, bDataBuf.Length, 0);

这儿是不是有点问题
[/Quote]
bDataBuf空间足够,iDataBufLen申明为ushort类型,所以转换一下。这里会有什么问题?
铛铛 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用楼主 tanbiao1987 的回复:]
iDataBufLen = (ushort)accsock.Receive(bDataBuf, bDataBuf.Length, 0);
[/Quote]
这儿是不是有点问题

111,121

社区成员

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

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

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