项目框架:
服务端:
MainForm.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace chatDemon
{
public partial class MainForm : Form
{
List<Socket> ClientProxSocketList = new List<Socket>();
public MainForm()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
//1创建Socket
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2绑定端口IP
socket.Bind(new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text)));
//开启侦听
socket.Listen(10);//等待连接的队列里连接的个数:同时来了100个连接请求,只能处理1个连接,队列里面放10个等待连接的客户端,其他的返回错误消息。
//开始接受客户端的连接
ThreadPool.QueueUserWorkItem(new WaitCallback(AcceptClientConnect), socket);
btnStart.Enabled = false;
}
public void AcceptClientConnect(object socket)
{
//Socket proxSocket = socket.Accept();//Accept方法一定放在异步线程里while循环里
var serverSocket = socket as Socket;
this.AppendTextToTextLog("服务器端开始接收客户端的连接");
while (true)
{
var proxSocket = serverSocket.Accept();//proxSocket:代理Socket
this.AppendTextToTextLog(string.Format("客户端:{0}连接上了", proxSocket.RemoteEndPoint.ToString()));
ClientProxSocketList.Add(proxSocket);
//不停的接收当前链接的客户端发来的消息
//proxSocket.Receive();
ThreadPool.QueueUserWorkItem(new WaitCallback(ReceiveData), proxSocket);
}
}
//接收客户端的消息
public void ReceiveData(object socket)
{
var proxSocket = socket as Socket;
byte[] data = new byte[1024 * 1024];
while (true)
{
int len = 0;
try
{
len = proxSocket.Receive(data, 0, data.Length, SocketFlags.None); //proxSocket接收到的数据放到data缓冲数组里面,起始地址为0,长度为data数组的长度,并返回接收到的数据的字节个数
}
catch (Exception ex)
{
//异常退出
AppendTextToTextLog(string.Format("客户端:{0}非正常退出", proxSocket.RemoteEndPoint.ToString()));
ClientProxSocketList.Remove(proxSocket);
StopConnected(proxSocket);
return;
}
if (len <= 0)
{
//客户端正常退出
AppendTextToTextLog(string.Format("客户端:{0}正常退出", proxSocket.RemoteEndPoint.ToString()));
ClientProxSocketList.Remove(proxSocket);
StopConnected(proxSocket);
return;//让方法结束,终结当前接收客户端数据的异步线程
}
//把接收到的数据放到文本框上去
string str = Encoding.Default.GetString(data, 0, len);
AppendTextToTextLog(string.Format("接收到客户端:{0}的消息是:{1}", proxSocket.RemoteEndPoint.ToString(), str));
}
}
private void StopConnected(Socket proxSocket)
{
try
{
if (proxSocket.Connected)
{
proxSocket.Shutdown(SocketShutdown.Both);
proxSocket.Close(100);
}
}
catch (Exception ex)
{
}
}
//往日志的文本框上追加数据
public void AppendTextToTextLog(string txt)
{
if (txtLog.InvokeRequired)
{
//同步方法
txtLog.Invoke(new Action<string>(s =>
{
this.txtLog.Text = string.Format("{0:G}