C#通过socket 异步传输数据功能已实现,如果网络不好的情况(电信服务器给网通服务器发送数据)偶尔会出现数据丢失 客户端发送数据成功,但服务端接口不到,如何才能避免网络不好的情况下数据正常接收?如果帮我侧地解决掉这个问题,绝对按标题说的给帮我解决问题的朋友打200元,绝不食言!一下是我的代码--------------------------------------- 服务端代码 用线程调用 Listen()方法 private void Listen()
{ string strIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
if (strIP.Length < 9)
{
strIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].ToString();
} IPAddress ip = IPAddress.Parse(strIP);
IPEndPoint ipe = new IPEndPoint(ip, 8889);
sockets = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sockets.Bind(ipe);
sockets.Listen(500);
while (isRun)
{
Control.CheckForIllegalCrossThreadCalls = false; try
{
allDone.Reset();
sockets.BeginAccept(new AsyncCallback(AcceptCallback), sockets);
allDone.WaitOne();
}
catch
{ }
}
}
private void AcceptCallback(IAsyncResult ar)
{
try
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar); StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
catch
{
}
}
private void ReadCallback(IAsyncResult ar)
{
try
{
string content = string.Empty; StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead = handler.EndReceive(ar); if (bytesRead > 0)
{
state.sb.Append(Encoding.Default.GetString(state.buffer, 0, bytesRead));
string info = state.sb.ToString(); }
}
}
catch
{ }
}
{ string strIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
if (strIP.Length < 9)
{
strIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].ToString();
} IPAddress ip = IPAddress.Parse(strIP);
IPEndPoint ipe = new IPEndPoint(ip, 8889);
sockets = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sockets.Bind(ipe);
sockets.Listen(500);
while (isRun)
{
Control.CheckForIllegalCrossThreadCalls = false; try
{
allDone.Reset();
sockets.BeginAccept(new AsyncCallback(AcceptCallback), sockets);
allDone.WaitOne();
}
catch
{ }
}
}
private void AcceptCallback(IAsyncResult ar)
{
try
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar); StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
catch
{
}
}
private void ReadCallback(IAsyncResult ar)
{
try
{
string content = string.Empty; StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead = handler.EndReceive(ar); if (bytesRead > 0)
{
state.sb.Append(Encoding.Default.GetString(state.buffer, 0, bytesRead));
string info = state.sb.ToString(); }
}
}
catch
{ }
}
解决方案 »
- 关于DEV控件GridControl中repositoryItemLookUpEdit加载数据不显示问题
- winform 求在固定窗体活动,不在其他区域活动的实例
- 求指教!关于定义服务器与客户端间消息格式
- 求算法:求枚舉子集合的算法
- (100分)求助在Window Service环境下使用回调函数(在线等)
- vs2005开发winform控件,怎么在其他电脑上网页注册?
- 用摄像头录象的问题.
- 怎么用其它帐户访问另一个帐户的私有文件夹
- 关于系统事件的调用
- 谁用.net搞过office编程?
- webservice 自动完成出错
- 把 treeview 保存到 txt文本文档之中 之后下次运行程序 会自动加载txt文本中的节点!!!!求各位大神帮忙 周三就要交了!!!
其次个人感觉csdn里面分比钱重要。。感觉楼主还是胆子小点。你把钱放在猪八戒上面,估计现在任务已经解决了。
好的,现在的问题是如何检测掉线的问题,在 sockets.BeginAccept方法中.NET封装了一些异常捕获,在SocketException中: try{
//...
}
catch (SocketException e)
{
//10035 == WSAEWOULDBLOCK
if (e.NativeErrorCode.Equals(10035))
{
//仍然处于连接状态,但是发送可能被阻塞
}
else
{
//连接错误,返回错误代码:e.NativeErrorCode
Socket_e.ResCode = e.NativeErrorCode.ToString();
SocketEvent(this, Socket_e);
return;
}
}
catch (Exception e)
{
//其他错误
Socket_e.ResCode = e.ToString();
SocketEvent(this, Socket_e);
return;
}
如果是UDP的连接就要考虑丢包的解决方案。一般是在判断包头的信息,重组,丢弃等做法。
首先给每次发送的消息编号,使用GUID即可,如果是发送XML更佳。当消息发送到服务器端后,服务器端返回一个确认消息给客户端,确认消息也要带上刚收到的消息的编号,这样客户端得到了这个确认消息就认为服务器端正常接收,否则就有可能接收失败,如果未收到确认消息(也可能是确认消息发送失败),客户端再次发送上次的消息,编号仍旧用上次的,这样服务器端即使重复收到了消息,也可以通过编号来识别是否是上次的消息重发了。
{
string host = "192.168.1.5";
int port = 8888;
Thread thread;
int rcount;
int fcount;
int sendcount = 1;
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{ thread = new Thread(new ThreadStart(send));
thread.Start();
}
private void UpdateUI(object o, System.EventArgs e)
{
sendcount += 1;
label1.Text = o.ToString();
}
private void send()
{
string msg = "";
for (int i = 0; i < 10000; i++)
{
msg = "第" + i + "次发送数据";
TcpClient client = new TcpClient();
client.Connect(host, port);
NetworkStream ns = client.GetStream();
ns.ReadTimeout = 1000;
byte[] bs = Encoding.Default.GetBytes(msg);
bool isSend = true;
while (isSend)
{
if (client.Connected == false)
{
client.Close();
client = new TcpClient();
client.Connect(host, port);
ns = client.GetStream();
ns.ReadTimeout = 1000;
}
ns.Write(bs, 0, bs.Length);
try
{
if (bs[0] == ns.ReadByte())
{
isSend = false;
label1.BeginInvoke(new System.EventHandler(UpdateUI), "send ok" + (rcount++));
}
else
{
break;
}
}
catch (Exception ex)
{
label1.BeginInvoke(new System.EventHandler(UpdateUI), "send fail" + (fcount++));
}
Thread.Sleep(1000);
}
client.Close();
}
}
}
Thread thread;
TcpListener listener;
int reqeustcount = 0; /// <summary>
/// 开始监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
thread = new Thread(new ThreadStart(Listen));
thread.Start();
Rolling();
} /// <summary>
/// 停止监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
try
{
listener.Stop();
thread.Abort();
}
catch(Exception ex)
{
throw ex;
}
Rolling();
}
private void Rolling()
{
richTextBox1.SelectionStart = richTextBox1.Text.Length;
richTextBox1.ScrollToCaret();
}
private void UpdateUI(object o, System.EventArgs e)
{
richTextBox1.AppendText("\n" + o.ToString());
}
private void Listen()
{
try
{
string hostname = System.Net.Dns.GetHostName();
IPHostEntry ipEntry = Dns.GetHostEntry(hostname);
IPAddress ip = ipEntry.AddressList[0];
listener = new TcpListener(IPAddress.Any, 8889);
listener.Start();
bool done = false;
reveidata = new byte[1000];
while (!done)
{
reqeustcount += 1;
Socket client = listener.AcceptSocket();
try
{
byte[] returnNum = new byte[1];
client.Receive(reveidata);
string str = Encoding.Default.GetString(reveidata);
richTextBox1.BeginInvoke(new System.EventHandler(UpdateUI), "第:" + reqeustcount.ToString() + "接收数据 " + str);
returnNum[0] = reveidata[0];
client.Send(returnNum);
}
catch (Exception e)
{
richTextBox1.BeginInvoke(new System.EventHandler(UpdateUI), "端口被占用 ");
}
}
}
catch(Exception ex)
{
throw ex;
}
}
ping XXX.XXX.XXX.XXX -t
发现有TIMEOUT的情况直接回给领导...这种事情你的小罗罗..还解决个毛啊.....电信..网通内部都是走的私网..网络有丢包..说不定是那个交换机设备不好呢...
你要做的是网络不好..比如网络断了..重连多少次..失败了..上报一个告警..就完事了...不要一直重连...这样有的设备会认为是攻击的...会出大事的...
{
client.Close();
client = new TcpClient();
client.Connect(host, port);
ns = client.GetStream();
ns.ReadTimeout = 1000;
} 这个地方做个判断,不理解,如果前一次的连接不成功,你再连一次,如果再连一次不成功呢?
你能直接发送数据?
哈哈,看到你骂WaitHandle不止一次了,确实B4 MSND的这个例子
try
{
bytesRead = handler.EndReceive(ar);// Read data from the client socket.
}
catch (Exception ex)
{
//抛出异常 远程主机强迫关闭一个现在的连接
}
再也接收不到数据了??
比如CRC16校验什么的