socket实践-第一个入门案例
效果和项目结构


Socket类成员方法
- Bind():绑定终结点
- Listen():开始监听指定的端口
- AcceptAsync():接受客户端连接,如果返回Socket对象不为空,说明有客户端连接
- ConnectAsync():连接服务器端
- ReceiveAsync():接收消息
- SendAsync():发送消息
![]()
实现
服务器端
- 第一步:使用指定的地址族、套接字类型和协议new一个socket对象
- 第二步:通过传入的IP和端口,socket对象与终结点相关联
- 第三步:监听
- 第四步:接受客户端,这里递归异步方法,如果Socket不为null,递归执行接收消息的异步方法
- 第五步:把控制台的输入发送给所有已建立连接的客户端
view code
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace SocketUtil
{
public class SocketServer
{
private int _port;
private string _ip;
private Socket _listener;
private List<Socket> sockets = new List<Socket>();
public SocketServer(int port)
{
_ip = "127.0.0.1";
_port = port;
}
public SocketServer(string ip, int port)
{
_ip = ip;
_port = port;
}
public async Task StartListening()
{
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress address = IPAddress.Parse(_ip);
IPEndPoint iPEndPoint = new IPEndPoint(address, _port);
_listener.Bind(iPEndPoint);
_listener.Listen(10);
}
public async Task AcceptAsync()
{
Socket socket = await _listener.AcceptAsync();
AcceptAsync();
if (socket != null)
{
sockets.Add(socket);
Console.WriteLine("当前连接客户端数:" + sockets.Count);
await ReceiveAsync(socket);
}
}
public async Task ReceiveAsync(Socket socket)
{
byte[] byteMsg = new byte[1024 * 1024 * 2];
int res = await socket.ReceiveAsync(byteMsg, SocketFlags.None);
ReceiveAsync(socket);
if (res > 0)
{
string msg = Encoding.UTF8.GetString(byteMsg, 0, res);
Console.WriteLine(msg);
}
}
public async Task SendAsync(string msg)
{
byte[] byteMsg = Encoding.UTF8.GetBytes(msg);
foreach (var socket in sockets)
{
await socket.SendAsync(byteMsg, SocketFlags.None);
}
}
public void Close()
{
_listener.Shutdown(SocketShutdown.Both);
_listener.Close();
}
}
}
控制台提供程序作为宿主
view code
using SocketUtil;
using System;
using System.Threading.Tasks;
namespace Socket.Server
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("输入:quit,关闭服务器。");
SocketServer server = new SocketServer(12345);
await server.StartListening();
await server.AcceptAsync();
while (true)
{
string op = Console.ReadLine();
if (op == "quit")
break;
else
await server.SendAsync(op);
}
}
}
}
客户端
- 第一步:使用指定的地址族、套接字类型和协议new一个socket对象
- 第二步:通过传入的IP和端口,socket对象与终结点建立连接(
ConnectAsync方法) - 第三步:子线程递归执行接收消息的异步方法
- 第四步:把控制台的输入发送给服务器端
view code
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace SocketUtil
{
public class SocketClient
{
private string _ip;
private int _port;
private Socket client;
public SocketClient(int port)
{
_ip = "127.0.0.1";
_port = port;
}
public SocketClient(string ip, int port)
{
_ip = ip;
_port = port;
}
public async Task StartClient()
{
IPAddress ipAddress = IPAddress.Parse(_ip);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, _port);
client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
await client.ConnectAsync(remoteEP);
Console.WriteLine("已经建立连接。");
}
public async Task ReceiveAsync()
{
byte[] byteMsg = new byte[1024 * 1024 * 2];
var res = await client.ReceiveAsync(byteMsg, SocketFlags.None);
ReceiveAsync();
if (res > 0)
{
string msg = Encoding.UTF8.GetString(byteMsg, 0, res);
Console.WriteLine(msg);
}
}
public async Task SendAsync(string msg)
{
byte[] byteMsg = Encoding.UTF8.GetBytes(msg);
//client.BeginSend(byteMsg, 0, byteMsg.Length, SocketFlags.None, new AsyncCallback(SendCallback), null);
await client.SendAsync(byteMsg, SocketFlags.None);
}
public void Close()
{
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
}
控制台提供程序作为宿主
view code
using SocketUtil;
using System;
using System.Threading.Tasks;
namespace Socket.Client
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("输入:quit,关闭客户端。");
SocketClient client = new SocketClient(12345);
await client.StartClient();
await Task.Run(() =>
{
client.ReceiveAsync();
});
while (true)
{
string op = Console.ReadLine();
if (op == "quit")
break;
else
await client.SendAsync(op);
}
}
}
}
小记:以上只是简单的例子供参考理解,很多细节问题还需要注意:可以再进一步抽象代码,异常处理,递归异步方法是否带来问题?


浙公网安备 33010602011771号