1.搭建服务器
用一个类 Server 来封装服务器有以下
成员变量 Socket serverSocket;//服务器套接字
List<Socket>clients = new List<Socket>();//用户列表
成员函数:
1.开启服务器
public void Start()
{
//启动服务器 绑定一个终端
serverSocket.Bind(new IPEndPoint(IPAddress.Any,12321));
//IPAddress.Any任何的IP地址都可以作为服务器
//12321 服务器端口 电脑端口范围 0-65535
serverSocket.Listen(10);
//挂起10个连接
Console.WriteLine("服务器启动成功!");
//用来接收用户端连接的线程
Thread acceptThread = new Thread(Accept);
acceptThread.IsBackground = true;
acceptThread.Start();
}
开启服务器后开启接收用户连接的线程
2.接收用户连接
private void Accept()
{
//接收一个连接 这里会形成阻塞
Socket clientSocket = serverSocket.Accept();
//将新连接的用户加入到用户列表中
clients.Add(clientSocket);
IPEndPoint remoteEndPoint = clientSocket.RemoteEndPoint as IPEndPoint;
Console.WriteLine(remoteEndPoint.Address + "[" + remoteEndPoint.Port + "]" + "成功连接");
//接收用户消息的线程
Thread receivethread = new Thread(Receive);
receivethread.IsBackground = true;
receivethread.Start(clientSocket);
//尾递归 继续接收连接
Accept();
}
用户连接后开启为此用户开启接收消息的线程
3.接收用户消息
//接收用户端信息
private void Receive(Object obj)
{
//注意委托只能传Object对象
Socket clientSocket = obj as Socket;
IPEndPoint remoteEndPoint = clientSocket.RemoteEndPoint as IPEndPoint;
try
{
byte[] msg = new byte[1024];
int msgLen = clientSocket.Receive(msg);
//服务器输出接收的消息
Console.WriteLine(remoteEndPoint.Address+ "[" + remoteEndPoint.Port + "]" + " : " + Encoding.UTF8.GetString(msg, 0, msgLen));
//向其他用户广播消息
Broadcast(clientSocket, remoteEndPoint.Address + "[" + remoteEndPoint.Port + "]" + " : " + Encoding.UTF8.GetString(msg, 0, msgLen));
//尾递归
Receive(clientSocket);
}
catch
{
//有用户断开连接就向其他用户广播
Console.WriteLine(remoteEndPoint.Address + "[" + remoteEndPoint.Port + "]" + "已断开");
Broadcast(clientSocket, remoteEndPoint.Address + "[" + remoteEndPoint.Port + "]" + "已断开");
clients.Remove(clientSocket);
}
}
用户断开连接之后移除该用户
4.将消息广播给其他用户
private void Broadcast(Socket client, string msg)
{
//client 发送消息的用户
//消息
foreach (var item in clients)
{
if(item == client)
{
}
else
{
item.Send(Encoding.UTF8.GetBytes(msg));
}
}
}
如果接收到发送消息的用户的消息后广播给其他用户
5.主函数
主函数在另外一个类里面
static void Main(string[] args)
{
Server server = new Server();
server.ServerControl();
server.Start();
Console.ReadKey();
}
2.搭建用户端
用一个类 Client 来封装服务器有以下
成员变量 Socket clientSocket;//服务器套接字
成员函数:
1.连接服务器
public void Connet(string ip,int port)
{
clientSocket.Connect(ip, port);
Console.WriteLine("客户端连接成功!");
//开启接收信息的线程
Thread receiveThread = new Thread(Receive);
receiveThread.IsBackground = true;
receiveThread.Start();
}
需要服务器的ip 以及端口
2.发送消息
public void Send(string msg)
{
clientSocket.Send(Encoding.UTF8.GetBytes(msg));
}
调用Send函数发送消息 消息为byte[]类型
3.接收消息
public void Receive()
{
try
{
byte[] msg = new byte[1024];
int msgLen = clientSocket.Receive(msg);
//接收的消息是一个byte[]
Console.WriteLine(Encoding.UTF8.GetString(msg, 0, msgLen));
//尾递归
Receive();
}
catch
{
Console.WriteLine("服务器断开!");
}
}
4.主函数
主函数在另外一个类中
static void Main(string[] args)
{
Client client = new Client();
client.ClientControl();
client.Connet("127.0.0.1", 12321);
IPEndPoint remoteEndPoint = client.clientSocket.LocalEndPoint as IPEndPoint;
string msg = Console.ReadLine();
while (msg != "quit")
{
client.Send(msg);
Console.WriteLine(remoteEndPoint.Address + "[" + remoteEndPoint.Port + "]" + " : " + msg);
msg = Console.ReadLine();
}
}
效果
1.先开启服务器
2.开启三个用户
3.每个用户发消息 断开一个用户
4.看图
成功!!