关于c#的Socket异步网络编程问题
答案:3 悬赏:40
解决时间 2021-01-08 09:42
- 提问者网友:难遇难求
- 2021-01-07 12:22
关于c#的Socket异步网络编程问题
最佳答案
- 二级知识专家网友:风格不统一
- 2021-01-07 13:58
这样的写法有点问题:
1)服务器端既然采用了异步方式Accept,就没有必要再启线程
2)估计allDone是一个ManualResetEvent。用ManualResetEvent的目的什么呢?
服务器端采用异步Accept的代码其实很简单,也不需要ManualResetEvent同步
public class AppTCPServer
{
public AppTCPServer(string localIP, int port)
{
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
EndPoint localEP = new IPEndPoint(IPAddress.Parse(localIP), port);
socket.Bind(localEP);
socket.Listen(100);
socket.BeginAccept(AcceptAsync, socket);
}
private void AcceptAsync(IAsyncResult ar)
{
Socket socket = ar.AsyncState as Socket;
try
{
Socket client = socket.EndAccept(ar);
Console.WriteLine("客户端连接成功!客户端:{0}", client.RemoteEndPoint.ToString());
if (OnConnected != null)
{
OnConnected(this, new ClientConnectedEventArgs(client));
}
}
catch (Exception e)
{
Console.WriteLine("AcceptAsync发生异常,异常信息:
{0}", e.Message);
}
finally
{
//继续异步Accept
socket.BeginAccept(AcceptAsync, socket);
}
}
//客户端连接后的事件 OnConnect
public event EventHandler OnConnected;
}
///
/// 事件参数:接收客户端连接后的事件参数
///
public class ClientConnectedEventArgs : EventArgs
{
public ClientConnectedEventArgs(Socket clientSocket)
{
ClientSocket = clientSocket;
}
public Socket ClientSocket { get; private set; }
}
class Program
{
static void Main(string[] args)
{
AppTCPServer server = new AppTCPServer("127.0.0.01", 8000);
server.OnConnected += server_OnConnected;
Console.WriteLine("按任意键结束程序……");
Console.ReadKey();
}
static void server_OnConnected(object sender, ClientConnectedEventArgs e)
{
Socket client = e.ClientSocket;
string hello = "Hello from AppTCPServer";
client.Send(Encoding.Default.GetBytes(hello));
}
} 客户端测试程序
class Program
{
static void Main(string[] args)
{
//模拟100个客户连接服务器
for (int i = 0; i < 100; i++)
{
Socket socket = ConnectToServer("127.0.0.1", 8000);
byte[] buffer = new byte[1024];
int bytesRecevied = socket.Receive(buffer, buffer.Length, SocketFlags.None);
byte[] messageBytes = new byte[bytesRecevied];
Array.Copy(buffer, messageBytes, bytesRecevied);
Console.WriteLine(Encoding.Default.GetString(messageBytes));
socket.Disconnect(false);
socket.Close();
}
Console.ReadKey();
static Socket ConnectToServer(string serverIP, int serverPort)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint localEP = new IPEndPoint(IPAddress.Any, 0);
socket.Bind(localEP);
socket.Connect(new IPEndPoint(IPAddress.Parse(serverIP), serverPort));
return socket;
}
}
1)服务器端既然采用了异步方式Accept,就没有必要再启线程
2)估计allDone是一个ManualResetEvent。用ManualResetEvent的目的什么呢?
服务器端采用异步Accept的代码其实很简单,也不需要ManualResetEvent同步
public class AppTCPServer
{
public AppTCPServer(string localIP, int port)
{
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
EndPoint localEP = new IPEndPoint(IPAddress.Parse(localIP), port);
socket.Bind(localEP);
socket.Listen(100);
socket.BeginAccept(AcceptAsync, socket);
}
private void AcceptAsync(IAsyncResult ar)
{
Socket socket = ar.AsyncState as Socket;
try
{
Socket client = socket.EndAccept(ar);
Console.WriteLine("客户端连接成功!客户端:{0}", client.RemoteEndPoint.ToString());
if (OnConnected != null)
{
OnConnected(this, new ClientConnectedEventArgs(client));
}
}
catch (Exception e)
{
Console.WriteLine("AcceptAsync发生异常,异常信息:
{0}", e.Message);
}
finally
{
//继续异步Accept
socket.BeginAccept(AcceptAsync, socket);
}
}
//客户端连接后的事件 OnConnect
public event EventHandler
}
///
/// 事件参数:接收客户端连接后的事件参数
///
public class ClientConnectedEventArgs : EventArgs
{
public ClientConnectedEventArgs(Socket clientSocket)
{
ClientSocket = clientSocket;
}
public Socket ClientSocket { get; private set; }
}
class Program
{
static void Main(string[] args)
{
AppTCPServer server = new AppTCPServer("127.0.0.01", 8000);
server.OnConnected += server_OnConnected;
Console.WriteLine("按任意键结束程序……");
Console.ReadKey();
}
static void server_OnConnected(object sender, ClientConnectedEventArgs e)
{
Socket client = e.ClientSocket;
string hello = "Hello from AppTCPServer";
client.Send(Encoding.Default.GetBytes(hello));
}
} 客户端测试程序
class Program
{
static void Main(string[] args)
{
//模拟100个客户连接服务器
for (int i = 0; i < 100; i++)
{
Socket socket = ConnectToServer("127.0.0.1", 8000);
byte[] buffer = new byte[1024];
int bytesRecevied = socket.Receive(buffer, buffer.Length, SocketFlags.None);
byte[] messageBytes = new byte[bytesRecevied];
Array.Copy(buffer, messageBytes, bytesRecevied);
Console.WriteLine(Encoding.Default.GetString(messageBytes));
socket.Disconnect(false);
socket.Close();
}
Console.ReadKey();
static Socket ConnectToServer(string serverIP, int serverPort)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint localEP = new IPEndPoint(IPAddress.Any, 0);
socket.Bind(localEP);
socket.Connect(new IPEndPoint(IPAddress.Parse(serverIP), serverPort));
return socket;
}
}
全部回答
- 1楼网友:过活
- 2021-01-07 16:16
很高兴协助你完成朋友
- 2楼网友:冷風如刀
- 2021-01-07 14:49
在AcceptCallback方法中,一方面要用newSocket.BeginReceive方法开始接收,一方面要调用Socket.BeginAccept继续接收连接尝试。追问这个我知道的,我在AcceptCallback中已经设置了allDone.set这样他会继续Socket.BeginAccept继续接收连接尝试 我问的意思是Socket.BeginAccept同时接收了多个连接,服务器就会出问题以后再用SET也没用了 请问出在哪里追答
不清楚allDone里边写了些什么……对照下代码吧,这个刚刚测试了能连接多个端。
///
/// 开启监听
///
public void StartListen()
{
try
{
ServerListnener = new Socket(GetAddress().Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
ServerListnener.Bind(GetAddress());
ServerListnener.Listen(200);
ServerListnener.BeginAccept(new AsyncCallback(AcceptCallback), ServerListnener);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
字数限制,后面加不上了……追问ServerListnener.BeginAccept这个一个只能连接一个客户端吧追答public void AcceptCallback(IAsyncResult ar)
{
try
{
Socket handler = ServerListnener.EndAccept(ar);
handler.Send(Encoding.Unicode.GetBytes("已连接到服务器!"));
this.sockets.Add(handler);
//buffer存储接收的数据,包装buffer与handler作为参数传递给ReceiveCallback
byte[] buffer = new byte[10240];
object[] obj = new object[2];
obj[0] = buffer;
obj[1] = handler;
handler.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), obj);
//重复回调,循环前面的操作
Socket NewListener = (Socket)ar.AsyncState;
NewListener.BeginAccept(new AsyncCallback(AcceptCallback), NewListener);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}追问兄弟 这个我都写好了,我的问题是这样的,只到ServerListnener.Listen(200);这一步后面的代码不写,客户端那边也能连接成功的,这种成功我服务器上怎么知道追答Socket handler = ServerListnener.EndAccept(ar);
这个handler是客户端连接上了才会创建的。里边有这个连接的详细信息(双方IPEndPoint之类的)。
在这句后面写个Console.WriteLine("XXX已连接");之类的没有问题。
不清楚allDone里边写了些什么……对照下代码吧,这个刚刚测试了能连接多个端。
///
/// 开启监听
///
public void StartListen()
{
try
{
ServerListnener = new Socket(GetAddress().Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
ServerListnener.Bind(GetAddress());
ServerListnener.Listen(200);
ServerListnener.BeginAccept(new AsyncCallback(AcceptCallback), ServerListnener);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
字数限制,后面加不上了……追问ServerListnener.BeginAccept这个一个只能连接一个客户端吧追答public void AcceptCallback(IAsyncResult ar)
{
try
{
Socket handler = ServerListnener.EndAccept(ar);
handler.Send(Encoding.Unicode.GetBytes("已连接到服务器!"));
this.sockets.Add(handler);
//buffer存储接收的数据,包装buffer与handler作为参数传递给ReceiveCallback
byte[] buffer = new byte[10240];
object[] obj = new object[2];
obj[0] = buffer;
obj[1] = handler;
handler.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), obj);
//重复回调,循环前面的操作
Socket NewListener = (Socket)ar.AsyncState;
NewListener.BeginAccept(new AsyncCallback(AcceptCallback), NewListener);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}追问兄弟 这个我都写好了,我的问题是这样的,只到ServerListnener.Listen(200);这一步后面的代码不写,客户端那边也能连接成功的,这种成功我服务器上怎么知道追答Socket handler = ServerListnener.EndAccept(ar);
这个handler是客户端连接上了才会创建的。里边有这个连接的详细信息(双方IPEndPoint之类的)。
在这句后面写个Console.WriteLine("XXX已连接");之类的没有问题。
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯