C# WinCE下使用Socket异步测试1000条讯息快速发送,发现大量丢失,客户端如何判断发送成功?

RikyZhang 2012-04-19 11:37:25
C# WinCE作为客户端,服务端在Win7上,用BeginSend方式循环发送1000条数据,会有大量丢失,如果延迟500毫秒则能成功。

1、而我这边的应用需求将投入大量的客户端,进行与服务端的通讯,那么是不是意味将来客户端很多的情况下异步收发将会有很多丢失情况呢?

2、无法在客户端判断发送成功的状态,必须根据服务器端回复消息来判断结果吗?

3、如果服务器一段时间无回复,客户端则重复发送吗?
...全文
528 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ridgepole81 2012-04-23
  • 打赏
  • 举报
回复
1、高频次并发容易造成异步接收无响应

2、发送方是无法判断成功状态的,必须接收方回复确认

3、发送无回复时,则认为发送失败,重复发送是必然的
zhengmeifu 2012-04-20
  • 打赏
  • 举报
回复
我也顶9楼的,要把一端做好了,才能测试另一端呀。服务器端稳定没问题吗?
当我遇上-你 2012-04-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
引用 4 楼 的回复:
UDP 不能用于大量数据的传输的,而且要保证数据的可靠性必须采用握手机制。


谢谢4楼的回答!
不过我用的TCP方式,由于经验不足,所以不知道如何来实现这样一个完善的机制应对大量的并发
最终是不是应根据客户端响应时间情况,来重复发送?
[/Quote]
wince并发,只有选择模式可以使用。
RikyZhang 2012-04-20
  • 打赏
  • 举报
回复

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Collections;
using System.Net;
using System.Windows.Forms;
using System.Threading;
using System.Data;

namespace SocketServer
{
public class SocketServer
{
private IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.159"), 6000); //本机地址

public Hashtable htClients = new Hashtable(); //存放客户端的列表

/// <summary>
/// 程序启动时就启动该线程侦听客户端的连接请求
/// </summary>
public void StartListening()
{
const int nPortListen = 6000;
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(ipEndPoint);
listener.Listen(1000);
listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener); 
}

/// <summary>
/// 客户端连接时触发连接事件
/// </summary>
/// <param name="ar"></param>
public void OnConnectRequest(IAsyncResult ar)
{
Socket listener = (Socket)ar.AsyncState;
Socket client = listener.EndAccept(ar);
Baohe bh = new Baohe(client);
htClients.Add(client.RemoteEndPoint, bh);
OnConnect(client);
//MessageBox.Show("Client:"+client.RemoteEndPoint.ToString());
listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);
}

/// <summary>
/// 连接后启动异步接收
/// </summary>
/// <param name="sock"></param>
public void OnConnect(Socket sock)
{
// Check if we were sucessfull
try
{
//sock.EndConnect( ar );
if (sock.Connected)
{
AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
byte[] buff = ((Baohe)htClients[sock.RemoteEndPoint]).buffer;//获取此宝盒对象的buff地址
sock.BeginReceive(buff, 0, buff.Length, SocketFlags.None, recieveData, sock);
}
else
MessageBox.Show("Unable to connect to remote machine", "Connect Failed!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unusual error during Connect!");
}
}

/// <summary>
/// 异步接收信息时触发事件
/// </summary>
/// <param name="ar"></param>
public void OnRecievedData(IAsyncResult ar)
{
Socket sock = (Socket)ar.AsyncState;
// Check if we got any data
try
{
int nBytesRec = sock.EndReceive(ar);
if (nBytesRec > 0)
{
byte[] buff = ((Baohe)htClients[sock.RemoteEndPoint]).buffer;//获取此客户端对象的buff地址
// Wrote the data to the List
string sRecieved = Encoding.UTF8.GetString(buff, 0, nBytesRec);
ParseMessage(sock, sRecieved);//根据消息做回复
// If the connection is still usable restablish the callback
SetupRecieveCallback(sock);
}
else
{
// If no data was recieved then the connection is probably dead
MessageBox.Show("disconnect from server " + sock.RemoteEndPoint);
sock.Shutdown(SocketShutdown.Both);
sock.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unusual error druing Recieve!");
}
}

/// <summary>
/// 异步接收继续开启
/// </summary>
/// <param name="sock"></param>
public void SetupRecieveCallback(Socket sock)
{
byte[] buff = ((Baohe)htClients[sock.RemoteEndPoint]).buffer;//获取此客户端对象的buff地址
AsyncCallback recieveData = new AsyncCallback(OnRecievedData);//收到数据时回调数据处理函数
sock.BeginReceive(buff, 0, buff.Length, SocketFlags.None, recieveData, sock);
}

/// <summary>
/// 回复客户端
/// </summary>
/// <param name="sock"></param>
/// <param name="sRecieved"></param>
public void ParseMessage(Socket sock, string sRecieved)
{
//根据sRecieved设置bytedata回复内容
}


/// <summary>
/// 发送客户端消息(参数:发送内容、发送目标)
/// </summary>
public bool sendClient(string sendContext,string sendTarget)
{

Socket clientSocket = ((Baohe)htClients[sendTarget]).socket;//根据键找出一个客户端的socket连接
try
{
byte[] buffer = Encoding.UTF8.GetBytes(sendContext);
AsyncCallback sendcallback = new AsyncCallback(OnSendCallBack);
clientSocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, sendcallback, clientSocket); //发送命令
}
catch
{
return false;
}
return true;
}

public void OnSendCallBack(IAsyncResult ar)
{
Socket sock = (Socket)ar.AsyncState;
sock.EndSend(ar);
}

}
}

以上为服务端代码,望各位大虾帮忙指点
RikyZhang 2012-04-20
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

wince并发,只有选择模式可以使用。
[/Quote]
我的并发主要存在于服务端,现在假设1000台客户端,随机的向服务端发送Socket.BeginSend,服务端就会有一部分BeginReceive没有触发CallBack事件来形成接收。这个正常吗?
RikyZhang 2012-04-20
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]
能确定服务器端没有问题吗?
[/Quote]

服务端与每个客户端建立单独的线程,单独的socket对象,做BeginReceive接收,我也不清楚这个会有什么问题吗?
一介布衣萧萧 2012-04-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

UDP 不能用于大量数据的传输的,而且要保证数据的可靠性必须采用握手机制。
[/Quote]

++
91program 2012-04-19
  • 打赏
  • 举报
回复
UDP 不能用于大量数据的传输的,而且要保证数据的可靠性必须采用握手机制。
91program 2012-04-19
  • 打赏
  • 举报
回复
无法在发送端判的,因为网络的原因。
RikyZhang 2012-04-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
每发一条都有个安全时间,即可以保证在这个时间内能够发送成功的。当发送N多条的时候,就需要考虑到这个问题,要不就会出现LZ类似的情况。

1、而我这边的应用需求将投入大量的客户端,进行与服务端的通讯,那么是不是意味将来客户端很多的情况下异步收发将会有很多丢失情况呢?
这个涉及到并发的问题,处理不好就会出现这样的情况
[/Quote]
如果客户端数量少,我可以考虑控制这个安全时间
而在客户端数量上千时,该如何处理并发时发送丢失的问题呢?
一介布衣萧萧 2012-04-19
  • 打赏
  • 举报
回复
每发一条都有个安全时间,即可以保证在这个时间内能够发送成功的。当发送N多条的时候,就需要考虑到这个问题,要不就会出现LZ类似的情况。

1、而我这边的应用需求将投入大量的客户端,进行与服务端的通讯,那么是不是意味将来客户端很多的情况下异步收发将会有很多丢失情况呢?
这个涉及到并发的问题,处理不好就会出现这样的情况
西山小月 2012-04-19
  • 打赏
  • 举报
回复
能确定服务器端没有问题吗?
RikyZhang 2012-04-19
  • 打赏
  • 举报
回复
补充问一句:我用的是TCP模式,是不是在大量并发的情况下BeginReceive收不到是很正常的呀?
RikyZhang 2012-04-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
UDP 不能用于大量数据的传输的,而且要保证数据的可靠性必须采用握手机制。
[/Quote]

谢谢4楼的回答!
不过我用的TCP方式,由于经验不足,所以不知道如何来实现这样一个完善的机制应对大量的并发
最终是不是应根据客户端响应时间情况,来重复发送?

19,502

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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