socket接受数据不完整是为什么?

bluesliuf 2017-10-21 08:35:07
数据是以这种形式发给我的
WWW###@@@ 3 4 ###@@@ 6 6 ###@@@ 3 3 ###@@@ 8 8 ###MMM
上面表示4条信息
当发100条的时候,能顺利接受并存入本地,可是发1000条时,数据就会接受不完全,会出现如下情况:
数据接受条数损失,还缺少包头
###@@@ 3 4 ###@@@ 6 6 ###@@@ 3 3 ###@@@ 8 8 ###

以下是我的代码:
namespace Socket__Show
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//监听来自客户端的连接请求
private void bt_connnect_Click(object sender, EventArgs e)
{

try
{
//点击开始监听时 在服务端创建一个负责监听IP和端口号的Socket
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//指定IP地址
IPAddress ip = IPAddress.Any;
//创建对象端口
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(tb_port.Text));

socketWatch.Bind(point);//绑定端口号
ShowMsg("监听成功!");
socketWatch.Listen(10);//设置监听

//创建监听线程
Thread thread = new Thread(Listen);
thread.IsBackground = true;
thread.Start(socketWatch);
}
//收集异常信息
catch { }

}

/// <summary>
/// 等待客户端的连接 并且创建与之通信的Socket
/// </summary>
Socket socketSend;
void Listen(object o)
{
try
{
Socket socketWatch = o as Socket;
while (true)
{
socketSend = socketWatch.Accept();//等待接收客户端连接
//服务端显示连接状态信息
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功!");
//开启一个新线程,执行接收消息方法
Thread r_thread = new Thread(Received);
r_thread.IsBackground = true;
r_thread.Start(socketSend);
}
}
catch { }
}
/// <summary>
/// 服务器端不停的接收客户端发来的消息
/// </summary>
/// <param name="o"></param>
void Received(object o)
{
try
{
Socket socketSend = o as Socket;
while (true)
{
//客户端连接服务器成功后,服务器接收客户端发送的消息,并将其存入缓冲区
byte[] buffer = new byte[4096];
//实际接收到的有效字节数
int len = socketSend.Receive(buffer);
if (len == 0)
{
break;
}
//将缓冲区的字节数据转换成字符串
string str = Encoding.UTF8.GetString(buffer, 0, len);

//调用方法将数据写入你指定的路径文件中,此处测试用的是"D:\data\3.txt"路径文件
WriteStringToFile(@"D:\data\3.txt", str);
ShowMsg("存取数据成功!!");
}
}
catch { }
}
//将提示信息显示在listbox中
void ShowMsg(string msg)
{
listBox1.Items.Add(msg + "\r\n");
}
//将字符串数据写入指定的文件
public static void WriteStringToFile(string fileName, string contents)
{ //初始化一个写入流对象
StreamWriter sWriter = null;
try
{ // 使用指定的路径、创建模式和读/写权限初始化 FileStream 类的新实例
FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write);
//实例化写入流对象
sWriter = new StreamWriter(fileStream);
//将字符串写入流
sWriter.Write(contents);
}
finally
{
if (sWriter != null)
{ //关闭写入流
sWriter.Close();
}
}
}


想请教一下大佬们这是什么原因?昨天还能接受1000多条的,今天就不行了 =-=
...全文
998 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
bluesliuf 2017-10-24
  • 打赏
  • 举报
回复
已经解决了,谢谢大家
xian_wwq 2017-10-23
  • 打赏
  • 举报
回复
引用 2 楼 bluesliuf 的回复:
代码应该具体怎么修改呢,我没学过C#,这个还是捣鼓了好久,老师又一直催 =-=,不给我时间
如果发送格式不修改,那就在接收时, 增加buffer或者队列,把数据先存下来, 然后启动一个新的解析线程,来专门解包 因为多个线程同时操作,需要对数据进行同步,防止脏数据
bluesliuf 2017-10-22
  • 打赏
  • 举报
回复
引用 1 楼 xian_wwq 的回复:
tcp是基于流的,所以接收方必须自行处理分包、组包,也就是常说的“粘包”处理。 简单说,发送的1, 12, 123 接收到的可能是11, 21,23 所以一般做法是报头+数据 在报头中携带数据长度信息, 如果后续接收不完整,继续接收; 如果超过数据长度,那么就需要自行切分。 否则解包的时候数据可能不完整,也可能比单个包长度还要多。
大佬,那我的代码应该具体怎么修改呢,我没学过C#,这个还是捣鼓了好久,老师又一直催 =-=,不给我时间
xian_wwq 2017-10-22
  • 打赏
  • 举报
回复
tcp是基于流的,所以接收方必须自行处理分包、组包,也就是常说的“粘包”处理。 简单说,发送的1, 12, 123 接收到的可能是11, 21,23 所以一般做法是报头+数据 在报头中携带数据长度信息, 如果后续接收不完整,继续接收; 如果超过数据长度,那么就需要自行切分。 否则解包的时候数据可能不完整,也可能比单个包长度还要多。

110,571

社区成员

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

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

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