想学学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"
服务端是异步的,代码如下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.EndAccept(iar);
如果你是在xp上测试的,那么试一试放到windows7上或者某一版windows server,或者找个软件把你的xp连接数改为1000.
从错误信息上判断,AcceptConn方法出现了错误,再从楼主描述的错误情况来看
判断
threaddelegate settext = delegate()
{
lock (this.RecieveMsg)
{
this.RecieveMsg.AppendText("服务器已连接" + ip.ToString() + "当前连接数"+this.clientsocketlist.Count.ToString());
}
};
肯定是这段出现了错误,你已经把委托要做的事情放到了异步方法内了;这里你应该要好好理解一下,委托的作用应该将方法独立开来,void SetText()
{
.....
}代码改成
Invoke(new threaddelegate(ISetText));
listener.BeginAccept(new AsyncCallback(AcceptConn), listener);3 另外另外这段代码里还有很多bug,例如没有对客户端非常断开作处理,导致一但有一个客户端关闭,服务端就崩溃了,应该把下面这个做异常判断处理
client.BeginSend(RecvData, 0, recv, SocketFlags.None, new AsyncCallback(SendData), client);
}
//继续接收来自来客户端的数据
client.BeginReceive(RecvData, 0, RecvData.Length, SocketFlags.None, new AsyncCallback(ReceiveData), 4 代码调试中发现这个判断完全没起作用,不知道在异步模式中是不是用这种方式来判断客户端断开的,继续研究中
if (recv == 0)
{
this.clientsocketlist.Remove(client);
client.Close();
}