首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

关于一个异步socket的有关问题

2012-06-22 
关于一个异步socket的问题想学学C#里面的同步socket和异步socket,于是下了个例子,虽然有bug不过改改勉强可

关于一个异步socket的问题
想学学C#里面的同步socket和异步socket,于是下了个例子,虽然有bug不过改改勉强可以用了,可是发现客户端多于一个就会报错
ex.Message = "The IAsyncResult object was not returned from the corresponding asynchronous method on this class.\r\nParameter name: asyncResult"
服务端是异步的,代码如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;

namespace WindowsFormsApplication1
{
  public partial class Form1 : Form
  {
  private delegate void threaddelegate();
  byte[] RecvData = new byte[65535];
  Socket serverSocket;
  List <Socket> clientsocketlist=new List<Socket>();
  public Form1()
  {
  InitializeComponent();
  }

  private void button1_Click(object sender, EventArgs e)
  {
  int connectcount = 100;
  serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  IPEndPoint iep = new IPEndPoint(IPAddress.Any,int.Parse(textBox1.Text));
  serverSocket.Bind(iep);
  this.RecieveMsg.AppendText("开始监听.........\n");
  serverSocket.Listen(connectcount);
  serverSocket.BeginAccept(new AsyncCallback(AcceptConn), serverSocket);
  }

  void AcceptConn(IAsyncResult iar)
  {
  try
  {
  Socket listener = (Socket)iar.AsyncState;
  Socket client = listener.EndAccept(iar);
  this.clientsocketlist.Add(client);
  IPAddress ip = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address;

  threaddelegate settext = delegate()
  {
  lock (this.RecieveMsg)
  {
  this.RecieveMsg.AppendText("服务器已连接" + ip.ToString() + "当前连接数"+this.clientsocketlist.Count.ToString());
  }
  };
  this.RecieveMsg.Invoke(settext);

  //开始接受来自该客户端的数据
  client.BeginReceive(RecvData, 0, RecvData.Length, SocketFlags.None, new AsyncCallback(ReceiveData), client);
  //继续接受其他客户端的连接
  listener.BeginAccept(new AsyncCallback(AcceptConn), client);
  }
  catch (Exception ex)
  {
  MessageBox.Show(ex.Message.ToString());
  }
  }
   
  void ReceiveData(IAsyncResult iar)
  {
  string strRecv;
  Socket client = (Socket)iar.AsyncState;
  int recv = client.EndReceive(iar);
  if (recv == 0)
  {
  this.clientsocketlist.Remove(client);
  client.Close();
  }
  else
  {
  threaddelegate settext = delegate()
  {
  lock (this.RecieveMsg)
  {
  string msgs = Encoding.Unicode.GetString(RecvData, 0, recv);
  this.RecieveMsg.AppendText(msgs);
  }
  };
  this.RecieveMsg.Invoke(settext);
   


  //将接收到的数据再发送给客户端
  client.BeginSend(RecvData, 0, recv, SocketFlags.None, new AsyncCallback(SendData), client);
  }
  //继续接收来自来客户端的数据
  client.BeginReceive(RecvData, 0, RecvData.Length, SocketFlags.None, new AsyncCallback(ReceiveData), client);
  }
   
  void SendData(IAsyncResult iar)
  {
  Socket client = (Socket)iar.AsyncState;
  int sent = client.EndSend(iar);
  }

  private void button3_Click(object sender, EventArgs e)
  {
  foreach (Socket clients in this.clientsocketlist)
  {
  byte[] sendmsg = Encoding.Unicode.GetBytes(this.textBox2.Text+"\n");
  clients.BeginSend(sendmsg, 0, sendmsg.Length, SocketFlags.None, new AsyncCallback(SendData), clients);
  }
  }
  }
}

有谁能帮忙看看哪里出的问题么?或者能给我一个较好的异步服务端代码么?

[解决办法]
没有异步委托出去
[解决办法]

探讨
错误~
ex.Message = "The IAsyncResult object was not returned from the corresponding asynchronous method on this class.\r\nParameter name: asyncResult"
位置在AcceptConn这个函数里面的
Socket client = listener.……

[解决办法]
问题肯定是出在你在一个Form实例的范围内实例化一个serverSocket。具体的代码可能还要自己测试。

说实在的,我从来没有想过在Form去启动过什么Socket服务。
[解决办法]
监听就没必要异步了,while都不加sleep的循环就可以了,建立连接就可有异步了..有的时候我还是习惯开线程去处理,因为我觉得思路清晰点,这个异步同步的,多了就乱了,尤其还是判断数据是否传完,是否异常等..
[解决办法]
探讨

错误~
ex.Message = "The IAsyncResult object was not returned from the corresponding asynchronous method on this class.\r\nParameter name: asyncResult"
位置在AcceptConn这个函数里面的
Socket client = liste……

[解决办法]
探讨

答11L 其实那段代码是网上下的,只是为了简单理解下C#里的异步socket,可惜就是bug太多了,而且对于大量的使用回调函数不是很习惯,以前感觉java和delphi中的socket阻塞模式思路很清晰,不过因为阻塞模式不是万能的,据说异步模式可以节省资源,所以想学习下

答12L,那个委托的代码确实是多余了,因为总是出问题,所以我临时加进去想判断下连接是否正确

[解决办法]
呵呵,上面我回复时其实只是看到了你的代码的Connect部分,根本没有耐心往下看。而且你的问题也是出在connect部分,所以也因此懒得往下看。

刚刚想起来,看看你的缓冲区怎么声明吧。可是一看吓了我一大跳,连这个RecvData 也是共享的啊?看来你真的被顺序处理的程序给害得不轻啊。这样共享一堆东西,你一旦并行处理就会出现各种诡异的bug了。
[解决办法]
推荐你看看C_网络编程.pdf,然后写socket程序,手到擒来

热点排行