socket 缓冲区接收一定量数据以后 如何复位

mm6268 2009-04-15 09:12:14
使C#做个小聊天工具
使用 socket 套接字实现异步接收,在进行接收图片时,因为图片没有压缩,直接已byte[]数组传送过来接收的
部分代码如下:

private Socket LocalSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private int size = 1024*64;
private Thread ListenThread;
private byte[] bytData;
/// <summary>
/// 监听方法,用于监听远程发送到本机的信息
/// </summary>
public void Listen()
{
ListenThread = new Thread(new ThreadStart(VideoListen));
ListenThread.Start();
}
/// <summary>
/// 监听线程
/// </summary>
private void VideoListen()
{
bytData = new byte[size]
while (true)
{
LocalSocket.BeginReceiveFrom(bytData, 0, bytData.Length, SocketFlags.None, ref ipeRemote, new AsyncCallback(ReceiveVideo), LocalSocket);
}
}
/// <summary>
/// 接收数据
/// </summary>
/// <param name="iar"></param>
private void ReceiveVideo(IAsyncResult iar)
{
int intRecv = 0;
try
{
intRecv = LocalSocket.EndReceiveFrom(iar, ref ipeRemote);
}
catch
{
//throw new Exception();
}

第二次执行到LocalSocket.BeginReceiveFrom(bytData, 0, bytData.Length, SocketFlags.None, ref ipeRemote, new AsyncCallback(ReceiveVideo), LocalSocket);

出现"未处理的SocketException"异常"由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作"。
这个异常怎么处理啊? 由于socket 的在接收数据时,需要给其分配个缓冲区,这里的缓冲区是 1024*64 就是64K大小(就算改大点,我改到1000000以后同样会报出这个异常,执行receive以后byte[]数组再清空已经和socket的缓冲区无关了),由于socket是在死循环中,所以socket的缓冲区没有被复位,所以再接收信息的时候,就是在刚才接受到得数据的缓冲区后再接收数据。
何如能吧receive的缓冲区给手动复位呢?
...全文
1046 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
tianqiang251616 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

问题 解决了,谢谢大家了。
一会让楼猪给分。
谁有图像压缩最好是拿C#写的源码啊?(最好带注释嘿嘿~)
给小弟我一份。JPEG,小波都行
小弟在这里谢谢 各位大虾了~
[/Quote]兄弟,请问你这个最后怎么解决的啊?我也遇到类似的问题,而且我想坚持用异步方式。请把你的解决方法告诉我发至811276859@qq.com,急用,谢谢~
aiai2498 2009-04-15
  • 打赏
  • 举报
回复
问题 解决了,谢谢大家了。
一会让楼猪给分。
谁有图像压缩最好是拿C#写的源码啊?(最好带注释嘿嘿~)
给小弟我一份。JPEG,小波都行
小弟在这里谢谢 各位大虾了~
diecode 2009-04-15
  • 打赏
  • 举报
回复
private void VideoListen()
{ string Result;
bytData = new byte[1024];
int BytesRcvd;
while (true)
{
BytesRcvd = AcceptSocket.Receive(bytData);
Result += Encoding.ASCII.GetString(byteData,0,BytesRcvd);
if(FindTheDataEnd...)break;
}
}

leiounasi 2009-04-15
  • 打赏
  • 举报
回复

private void VideoListen()
{
while (true)
{
bytData = new byte[size]
LocalSocket.BeginReceiveFrom(bytData, 0, bytData.Length, SocketFlags.None, ref ipeRemote, new AsyncCallback(ReceiveVideo), LocalSocket);
}
}


写到里面就可以了啊
diecode 2009-04-15
  • 打赏
  • 举报
回复
while (true)
{
LocalSocket.BeginReceiveFrom(bytData, 0, bytData.Length, SocketFlags.None, ref ipeRemote, new AsyncCallback(ReceiveVideo), LocalSocket);
}
你这个循环错了
begin?????都是些异步函数,即执行后立即返回的
如果socket已经关闭了,你的这个循环就要异常了
mm6268 2009-04-15
  • 打赏
  • 举报
回复
改成同步后的代码如下:
EndPoint ipeRemote =(EndPoint)(new IPEndPoint(IPAddress.Any,9000))
private void VideoListen()
{
bytData = new byte[size]
while (true)
{
LocalSocket.ReceiveFrom(byteData,ref ipeRemote);
}
}
接收大一点的信息,循环接收几次后就会出现:
未处理的“System.Net.Sockets.SocketException”类型的异常出现在 system.dll 中。

其他信息: 一个在数据报套接字上发送的消息大于内部消息缓冲器或其他一些网络限制,或该用户用于接收数据报的缓冲器比数据报小。

这个异常如何解决啊
如何 复位 缓冲器啊
aiai2498 2009-04-15
  • 打赏
  • 举报
回复
改成同步以后 我传个字符串进行实验,字符串9个字符,出现 “一个在数据报套接字上发送的消息大于内部消息缓冲器或其他一些网络限制,或该用户用于接收数据报的缓冲器比数据报小。”的异常。
aiai2498 2009-04-15
  • 打赏
  • 举报
回复
现在正改着呢呵呵~~
aiai2498 2009-04-15
  • 打赏
  • 举报
回复
while (true)
{
if (LocalSocket.Poll(5000, SelectMode.SelectRead))
{//每5ms查询一下网络,如果有可读数据就接收
LocalSocket.BeginReceiveFrom(bytData, 0, bytData.Length, SocketFlags.None, ref epRemote, new AsyncCallback(ReceiveData), LocalSocket);
}
}
这个是源码 楼主帮发那个 给删掉了
rtdb 2009-04-15
  • 打赏
  • 举报
回复
你虽然成对写的,但不是成对运行的,
你一个while (true),还没等数据进来呢,
BeginReceiveFrom就可以走了无数次了。
你这是同步的写法,直接改成ReceiveFrom就得了


aiai2498 2009-04-15
  • 打赏
  • 举报
回复
服务器的缓冲区最大能设置多大啊? 客户端传一个byte[623631] 为什么传过去了 ,服务器接收不到
aiai2498 2009-04-15
  • 打赏
  • 举报
回复
异步方式没有错啊,是成对出现的
我不懂电脑 2009-04-15
  • 打赏
  • 举报
回复
和你的发送端程序有关,由于你用的事udp协议,因此要确保你每次发送的数据长度小于服务端的缓冲区大小。另外最好在服务器确认收到一个数据报后,再发送下一个数据报。
rtdb 2009-04-15
  • 打赏
  • 举报
回复
已经用线程了,就没必要用异步接收方式了吧?直接用同步方式更简单。

好象你的异步接收方式用错了,你不能在连续多次调用BeginReceiveFrom()的,
它必须确保和EndReceiveFrom()是成对调用的。



aiai2498 2009-04-15
  • 打赏
  • 举报
回复
楼上的是接受文字吗?如果下机连续传送2次数据怎么办,还得重新启动线程吗?
txt_paul 2009-04-15
  • 打赏
  • 举报
回复
用完一个就关掉啊。

Socket 有时候用于上位机编程中,与下位机进行UDP通信。 我写的时候每用完一个socket ,立即调用 Close(). 不Close()你就挂掉了

110,533

社区成员

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

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

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