C# 多人聊天室(基于TCP协议)
2个客户端和1个服务端
客户端将消息发到服务端,服务端将消息进行群发(消息发送方除外),从而实现了多人聊天
客户端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Client
{
public partial class Form1 : Form
{
Socket socket = null;
public Form1()
{
InitializeComponent();
btnConnect.Click += BtnConnect_Click;
btnSend.Click += BtnSend_Click;
Task.Run(Receive);
}
private void Receive()
{
while (true)
{
if (socket == null) continue;
if (!socket.Connected) continue;
try
{
byte[] buffer = new byte[1024];
int len = socket.Receive(buffer);
if (len < 1) continue;
string msg = Encoding.UTF8.GetString(buffer, 0, len);
ShowMessage(msg + "\n");
}
catch (Exception ex)
{
ShowMessage(ex.Message + "\n");
socket = null;
}
}
}
private void BtnSend_Click(object sender, EventArgs e)
{
if (!socket.Connected)
{
ShowMessage($"未连接,无法发送");
return;
}
try
{
var buffer = Encoding.UTF8.GetBytes(rtxtSend.Text);
socket.Send(buffer);
ShowMessage($"发送到:{socket.RemoteEndPoint},消息:{rtxtSend.Text}");
}
catch (Exception ex)
{
ShowMessage($"发送失败:{socket.RemoteEndPoint},{ex.Message}");
socket = null;
}
}
private void BtnConnect_Click(object sender, EventArgs e)
{
if (socket != null && socket.Connected)
{
ShowMessage($"无需重复连接");
return;
}
try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ShowMessage($"LocalEndPoint={socket.LocalEndPoint},RemoteEndPoint={socket.RemoteEndPoint}");
var ipEndPoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
socket.Connect(ipEndPoint);
if (socket.Connected)
{
ShowMessage($"成功连接到:{socket.RemoteEndPoint}");
}
}
catch (Exception ex)
{
ShowMessage($"连接失败:{ex.Message}");
socket = null;
}
}
private void ShowMessage(string msg)
{
//子线程调用
if (rtxtLog.InvokeRequired)
{
rtxtLog.Invoke(new Action(() => rtxtLog.Text += msg + "\n"));
}
//主线程调用
else
{
rtxtLog.Text += msg + "\n";
}
}
}
}
服务端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Server
{
class Program
{
static Socket socket = null;
static void Main(string[] args)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.117"), 60000));
socket.Listen(10);
Console.WriteLine("已启动侦听");
Task.Run(Connect);
Console.ReadLine();
}
static List<Socket> socketPool = new List<Socket>();
static Socket acceptSocket = null;
static void Connect()
{
while (true)
{
try
{
acceptSocket = socket.Accept();
var receiveSocket = acceptSocket;
Console.WriteLine($"已接受连接:{receiveSocket.RemoteEndPoint}");
socketPool.Add(receiveSocket);
Task.Run(Receive);
}
catch (Exception ex)
{
Console.WriteLine($"连接失败:{ex.Message}");
}
}
}
static void Receive()
{
var receiveSocket = acceptSocket;
while (true)
{
if (receiveSocket == null) continue;
if (!receiveSocket.Connected) continue;
try
{
byte[] buffer = new byte[1024];
var len = receiveSocket.Receive(buffer);
if (len < 1) continue;
var msg = Encoding.UTF8.GetString(buffer, 0, len);
Console.WriteLine($"来自 {receiveSocket.RemoteEndPoint} 的消息 {msg}");
var responseBuffer = Encoding.UTF8.GetBytes($"来自{receiveSocket.RemoteEndPoint} 的消息:{msg}");
// receiveSocket.Send(responseBuffer);
//清理失效的连接
for (int i = socketPool.Count-1; i >=0 ; i--)
{
if (socketPool[i] == null || !socketPool[i].Connected)
{
socketPool.RemoveAt(i);
}
}
//广播消息(除了发送消息方之外的,全部广播)
foreach (var s in socketPool)
{
if (s!= receiveSocket)
{
s.Send(responseBuffer);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message+"\n");
}
}
}
}
}