C#网络编程学习(4)---Socket Tcp进阶之 使用异步循环接收客户端连接和信息
1、方法介绍
BeginAccept(AsyncCallback callback, object state);
异步开始监听客户端连接。
- callback为一个委托,在成功接收客户端连接时调用委托方法。
- 向委托方法中传递的参数
**EndAccept (IAsyncResult result);** 结束监听客户端连接,一般在委托中成功接收连接后使用。 1. **result**:它存储此异步操作的状态信息以及任何用户定义数据。 返回。使用**result.AsyncState** 可以接收传递过来的参数。
**BeginReceive (byte[] buffer, int offset, int size, SocketFlags flag, AsyncCallback callback, object state);** 异步接收服务器发送来的数据 1. 存储接收的数据 2. 从buffer哪开始存储数据 3. 要接受最大的字节数 4. SocketFlags 值的按位组合 5. 接收成功后调用的委托方法 6. 要传递的参数
2、服务器端
namespace Tcp服务器端
{
class Program
{
/// <summary>
/// 接收客户端发送数据数组
/// </summary>
static byte[] data = new byte[1024];
static void Main(string[] args)
{
StartServerAsync();
}
static void StartServerAsync()
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
serverSocket.Bind(point);
serverSocket.Listen(100);
//异步监听客户端连接
serverSocket.BeginAccept(AcceptCallBack,serverSocket);
Console.ReadKey();
}
/// <summary>
/// 接收到客户端连接时调用
/// </summary>
static void AcceptCallBack(IAsyncResult ar)
{
Console.WriteLine("一个客户端连接了进来\n");
Socket serverSocket = null;
try
{
//接收传递过来的main中的serverSocket
serverSocket = ar.AsyncState as Socket;
//结束接收,返回接收到的clientSocket
Socket clientSocket = serverSocket.EndAccept(ar);
clientSocket.Send(Encoding.UTF8.GetBytes("你好呀。。。客户端"));
//异步开始监听客户端传递数据
clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket); //从头开始存,最大数量,none,接收到客户端后执行的回调函数,要传递的参数(会被传递给回调函数)
//继续处理下一个客户端的连接,相当于一个伪递归
serverSocket.BeginAccept(AcceptCallBack, serverSocket);
}
catch (Exception e)
{
Console.WriteLine(e);
if (serverSocket != null)
serverSocket.Close();
}
}
/// <summary>
/// 接收到客户端发送的数据时调用
/// </summary>
static void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = null;
try
{
clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
//正常关闭的情况
if (count == 0)
{
Console.WriteLine("一个客户端正常断开了连接");
clientSocket.Close();
return;
}
Console.WriteLine("接收到数据:" + Encoding.UTF8.GetString(data, 0, count));
clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket); //从头开始存,最大数量,none,接收到客户端后执行的回调函数,要传递的参数
}
catch (Exception e)
{
//非正常关闭的情况
Console.WriteLine(e);
if (clientSocket != null)
clientSocket.Close();
}
}
}
}
3、客户端
namespace Tcp客户端
{
class Program
{
static void Main(string[] args)
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
clientSocket.Connect(point);
byte[] data = new byte[1024];
int length = clientSocket.Receive(data);
Console.WriteLine(Encoding.UTF8.GetString(data, 0, length));
//循环向服务器发送数据
while (true)
{
string s = Console.ReadLine();
//输入c正常退出,直接按×异常退出
if (s == "c")
{
clientSocket.Close();
return;
}
clientSocket.Send(Encoding.UTF8.GetBytes(s));
}
Console.ReadKey();
}
}
}
4、效果
服务器可以接收多个客户端连接
多个客户端都可以向服务器发送数据