君,已阅读到文档的结尾了呢~~
c#网络编程简单实现通信小例子
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
c 网络编程简单实现通信小例子
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口C#Socket异步通信在处理批量并发时有时出现数据重叠
代码如下:当并发数量较大时,会出现数据冲突,求改进方案
using&System.C
using&System.Collections.G
using&ponentM
using&System.D
using&System.D
using&System.L
using&System.T
using&System.Windows.F
using&System.N
using&System.Net.S
using&System.Collections.S
using&System.T
namespace&SocketServer
&&&&public&partial&class&frmMain&:&Form
&&&&&&&&static&int&count&=&0;
&&&&&&&&static&int&recvCount&=&0;
&&&&&&&&public&frmMain()
&&&&&&&&&&&&InitializeComponent();
&&&&&&&&private&delegate&void&ShowMsgHandler(string&msg);
&&&&&&&&IList&Socket&&clientList&=&new&List&Socket&();
&&&&&&&&Dictionary&Socket,&System.Threading.Timer&&clientArray&=&new&Dictionary&Socket,&System.Threading.Timer&();
&&&&&&&&private&void&ShowMsg(string&msg)
&&&&&&&&&&&&if&(!txtContent.InvokeRequired)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&txtContent.Text&=&msg&+&Environment.NewLine&+&txtContent.T
&&&&&&&&&&&&}
&&&&&&&&&&&&else
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&ShowMsgHandler&handler&=&new&ShowMsgHandler(ShowMsg);
&&&&&&&&&&&&&&&&BeginInvoke(handler,&new&object[]&{&msg&});
&&&&&&&&&&&&}
&&&&&&&&private&void&btnStartServer_Click(object&sender,&EventArgs&e)
&&&&&&&&&&&&IPAddress[]&localIPs;
&&&&&&&&&&&&localIPs&=&Dns.GetHostAddresses(Dns.GetHostName());
&&&&&&&&&&&&StringCollection&IpCollection&=&new&StringCollection();
&&&&&&&&&&&&foreach&(IPAddress&ip&in&localIPs)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if&(ip.AddressFamily&==&AddressFamily.InterNetwork)&//如果为IPv4
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&if&(Int32.Parse(txtPort.Text.ToString())&!=&0)
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&TcpListener&listener&=&new&TcpListener(ip,&Int32.Parse(txtPort.Text.ToString()));
&&&&&&&&&&&&&&&&&&&&&&&&listener.Start();
&&&&&&&&&&&&&&&&&&&&&&&&listener.BeginAcceptTcpClient(new&AsyncCallback(OnAcceptedTcpClient),&listener);
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&TcpListener&listener&=&new&TcpListener(ip,&6000);
&&&&&&&&&&&&&&&&&&&&&&&&listener.Start();
&&&&&&&&&&&&&&&&&&&&&&&&listener.BeginAcceptTcpClient(new&AsyncCallback(OnAcceptedTcpClient),&listener);
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&txtContent.Text&=&"Start&Listiner...";
&&&&&&&&&&&&&&&&&&&&btnStartServer.Enabled&=&
&&&&&&&&&&&&&&&&&&&&ShowMsg(ip.ToString());
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}&&&
&&&&&&&&byte[]&buffer&=&new&byte[1024];
&&&&&&&&public&void&TimerCallback(object&state)
&&&&&&&&&&&&
&&&&&&&&&&&&Socket&sock&=&(Socket)
&&&&&&&&&&&&if&(clientArray.Remove(sock))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&ShowMsg("TimerCallback");
&&&&&&&&&&&&}
&&&&&&&&&&&&sock.Close(100);
&&&&&&&&private&void&OnAcceptedTcpClient(IAsyncResult&ar)
&&&&&&&&&&&&if&(!ar.IsCompleted)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}
&&&&&&&&&&&&TcpListener&listener&=&(TcpListener)ar.AsyncS
&&&&&&&&&&&&TcpClient&client&=&listener.EndAcceptTcpClient(ar);
&&&&&&&&&&&&System.Threading.Timer&time&=&new&System.Threading.Timer(TimerCallback,&client.Client,&2);
&&&&&&&&&&&&clientArray.Add(client.Client,&time);
&&&&&&&&&&&&ShowMsg("连接成功&");
&&&&&&&&&&&&count++;
&&&&&&&&&&&&listener.BeginAcceptTcpClient(new&AsyncCallback(OnAcceptedTcpClient),&listener);
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&client.Client.BeginReceive(buffer,&0,&1024,&SocketFlags.None,&new&AsyncCallback(OnReceivedData),&client.Client);
&&&&&&&&&&&&}
&&&&&&&&private&void&OnReceivedData(IAsyncResult&ar)
&&&&&&&&&&&&if&(!ar.IsCompleted)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}
&&&&&&&&&&&&Socket&s&=&(Socket)ar.AsyncS
&&&&&&&&&&&&try
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&int&size&=&s.EndReceive(ar);
&&&&&&&&&&&&&&&&if&(size&&&0)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&string&str&=&System.Text.Encoding.Default.GetString(buffer,&0,&size);
&&&&&&&&&&&&&&&&&&&&&&&&ShowMsg(str);
&&&&&&&&&&&&&&&&&&&&}&&
&&&&&&&&&&&&&&&&&&&&recvCount++;
&&&&&&&&&&&&&&&&&&&&clientArray.Remove(s);
&&&&&&&&&&&&&&&&&&&&s.Shutdown(SocketShutdown.Both);
&&&&&&&&&&&&&&&&&&&&s.Close(100);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&clientArray.Remove(s);
&&&&&&&&&&&&&&&&&&&&s.Close(100);
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&}
//&&&&&&&&&&&&&&&&&s.BeginReceive(buffer,&0,&1024,&SocketFlags.None,&new&AsyncCallback(OnReceivedData),&s);
&&&&&&&&&&&&}
&&&&&&&&&&&&catch&(SocketException&)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&clientArray.Remove(s);
&&&&&&&&&&&&&&&&s.Close(100);
&&&&&&&&&&&&}
&&&&&&&&private&void&btnSend_Click(object&sender,&EventArgs&e)
&&&&&&&&&&&&byte[]&msg&=&System.Text.Encoding.Unicode.GetBytes(txtMsg.Text.Trim());
&&&&&&&&&&&&foreach&(Socket&s&in&clientList)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&s.BeginSend(msg,&0,&msg.Length,&SocketFlags.None,&new&AsyncCallback(OnSendMsg),&s);
&&&&&&&&&&&&}
&&&&&&&&private&void&OnSendMsg(IAsyncResult&ar)
&&&&&&&&&&&&if(!ar.IsCompleted)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}
&&&&&&&&&&&&Socket&s&=&(Socket)ar.AsyncS
&&&&&&&&&&&&s.EndSend(ar);
&&&&&&&&private&void&TotleCount_Click(object&sender,&EventArgs&e)
&&&&&&&&&&&&ShowMsg("连接数:"&+&count.ToString()&+"&&收包数:"&+&recvCount&+&"&现连接:&"&+&/*clientList.Count*/clientArray.Count);
有时候100个客户端同时发送数据,收到的数据有时显示正常,有时候将95号客户端的显示两次,96号客户端的没显示,这个只是只要连接成功了发送数据后就直接断开的的测试程序,虽然说buff是同一个,但是我想知道原因到底在哪
1.服务端accept一个client后&&不能使用同一个buffer接收数据&&
2.数据接收返回后,buffer不一定是完整的数据
引用&2&楼&xiaozhi_5638&的回复:1.服务端accept一个client后&&不能使用同一个buffer接收数据&&
2.数据接收返回后,buffer不一定是完整的数据
对于1这个我这是想简单的测试下,避免紊乱我可以为每个连接上的对象new一个buff,用完销毁丢到Socket字典中的,&2现在只假设一下数据流小于1024,这样数据会是完整的,但是有的数据出现多次,有的数据不出现这个问题实在不知道到底是为什么出现的
协议要订好&&约好头跟尾
引用&4&楼&huanggreat&的回复:协议要订好&&约好头跟尾
这个应该不是&协议相关的问题吧,比如100个客户并发,确实是收到了100个数据包,就代表应该是没有掉包的,但是在显示时候一个包显示了两次,另外一个包没显示
引用&3&楼&yc7369&的回复:Quote: 引用&2&楼&xiaozhi_5638&的回复:
1.服务端accept一个client后&&不能使用同一个buffer接收数据&&
2.数据接收返回后,buffer不一定是完整的数据
对于1这个我这是想简单的测试下,避免紊乱我可以为每个连接上的对象new一个buff,用完销毁丢到Socket字典中的,&2现在只假设一下数据流小于1024,这样数据会是完整的,但是有的数据出现多次,有的数据不出现这个问题实在不知道到底是为什么出现的
1这是为了测试什么?&所有的连接往一个缓冲区中写数据&&什么结果&&
如果前后两个连接数据同时到达&写入缓冲区后&就会覆盖&&总有一个连接的EndReceive()不会返回&或者返回了&size也为零
你不要以为客户端按顺序先后登录发送数据&&它们到达服务器的顺序就是一定是先后顺序的&&所以buffer用同一个没事儿&&不一定
引用&7&楼&xiaozhi_5638&的回复:如果前后两个连接数据同时到达&写入缓冲区后&就会覆盖&&总有一个连接的EndReceive()不会返回&或者返回了&size也为零
你不要以为客户端按顺序先后登录发送数据&&它们到达服务器的顺序就是一定是先后顺序的&&所以buffer用同一个没事儿&&不一定
到达服务器的这个顺序确实是未知的,
看样子C#&OnDatarecv回调&+&EndReceive对于批量并发共用一段缓冲区还是不靠谱的,那我还是改成每个Socket自带缓冲区的吧,这样这个问题确实是没了
对clientArray&操作不是多线程安全的
clientArray&&add&remove&时&lock试试
引用&8&楼&yc7369&的回复:Quote: 引用&7&楼&xiaozhi_5638&的回复:
如果前后两个连接数据同时到达&写入缓冲区后&就会覆盖&&总有一个连接的EndReceive()不会返回&或者返回了&size也为零
你不要以为客户端按顺序先后登录发送数据&&它们到达服务器的顺序就是一定是先后顺序的&&所以buffer用同一个没事儿&&不一定
到达服务器的这个顺序确实是未知的,
看样子C#&OnDatarecv回调&+&EndReceive对于批量并发共用一段缓冲区还是不靠谱的,那我还是改成每个Socket自带缓冲区的吧,这样这个问题确实是没了
从来都不应该这样用
学习学习下!
回复
即使是一小步也想与你分享【delphi】btnStartServer 在什么包里_百度知道