server 端
csharp
Socket serverSocket = null;
Socket ClientSocket = null;
List<Socket> listSocket=new List<Socket>();
private void btnlisten_Click(object sender, EventArgs e)
{
serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(txtIP.Text);
IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(txtPort.Text));
serverSocket.Bind(endpoint);
//同时监控几个客户端
serverSocket.Listen(10);
Task.Run((Action)ListentConnectSocket);//等价于 Action action=ListentConnectSocket;Task.Run(action);
//方法2
//Thread thd = new Thread(ListentConnectSocket);
//thd.IsBackground = true;
//thd.Start();
}
void ListentConnectSocket()
{
// 死循环
while (true)
{
try
{
ClientSocket = serverSocket.Accept(); //放在UI线程,会阻塞,所以放在另外一个线程
string sendMsg = "恭喜您,服务器连接成功!";
ClientSocket.Send(Encoding.Default.GetBytes(sendMsg));
//客户端IP、端口号
string ClientInfo = ClientSocket.RemoteEndPoint.ToString();
//方法1
//Action<string> action = delegate (string msg)
//{
// lsReceive.Items.Add(msg);
//};
//lsReceive.Invoke(action, ClientInfo);
//方法2 匿名方法
//lsReceive.Invoke((Action<string>)delegate(string msg) {
// lsReceive.Items.Add(msg);
//},ClientInfo);
// 方法3 lamda
lsReceive.Invoke(new Action<string>((msg) =>
{
listSocket.Add(ClientSocket);
lsReceive.Items.Add($"{msg} 上线啦");
}), ClientInfo);
}
catch (Exception ex)
{
lsReceive.Invoke(new Action<string>((msg) =>
{
lsReceive.Items.Add(msg);
}), $"发送信息失败;{ex.Message}");
break;
}
//开启接收信息
//方法1
//Thread thr = new Thread(ReceiveClientMsg);
//thr.IsBackground = true;
//thr.Start(ClientSocket);
//方法2
Action<Socket> action = new Action<Socket>(ReceiveClientMsg);
Task.Run(()=>action(ClientSocket));
}
}
private void ReceiveClientMsg(object clientSocket)
{
Socket client = clientSocket as Socket;
while (true)
{
byte[] recBuffer = new byte[1024];
int length = -1;
try
{
//Receive 是阻塞方法
length = client.Receive(recBuffer);
}
catch (Exception ex)
{
//客户端关闭应用程序
string str = client.RemoteEndPoint.ToString();
this.Invoke(new Action(() =>
{
lsReceive.Items.Add($"接收客户端:{str} 异常; {ex.Message}");
}));
break;
}
if (length == 0)
{
string str = client.RemoteEndPoint.ToString();
this.Invoke(new Action(() =>
{
lsReceive.Items.Add($"{str}:下线了!");
}));
break;
}
else
{
string msg = Encoding.Default.GetString(recBuffer, 0, length);
string msgStr = $"{DateTime.Now}【 接收客户端: {client.RemoteEndPoint.ToString()}】--- {msg}";
this.Invoke(new Action(() =>
{
lsReceive.Items.Add(msgStr + Environment.NewLine);
}));
}
}
}
private void btnSend_Click(object sender, EventArgs e)
{
Task.Run(new Action(()=> {
foreach (Socket item in listSocket)
{
item.Send(Encoding.Default.GetBytes(txtSend.Text));
}
}));
}
客户端
csharp
// 创建 Socket对象
Socket clientSocket = null;
private void btnConnect_Click(object sender, EventArgs e)
{
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
try
{
lstReceive.Items.Add("与服务器连接中。。。。");
clientSocket.Connect(endPoint);
//方法1
Action action = ReceiveMsg;
Task.Run(action);//开启线程
if (clientSocket.Connected)
{
lstReceive.Items.Add("服务器连接成功。。。。");
}
//方法2
//Thread thd = new Thread(ReceiveMsg);
//thd.IsBackground = true;
//thd.Start();
}
catch (Exception ex)
{
lstReceive.Items.Add($"连接失败:{ ex.ToString()}");
}
}
/// <summary>
/// 接收消息
/// </summary>
private void ReceiveMsg()
{
while (true)
{
//声明接受最大字节数
byte[] buffer = new byte[1024];
int length = -1;
try
{
length = clientSocket.Receive(buffer);
}
catch (Exception ex)
{
lstReceive.Invoke(new Action(() =>
{
lstReceive.Items.Add($"接收数据失败: {ex.Message}");
}));
break;
}
if (length > 0)
{
// 方法1
//byte[] temp = new byte[length];
//Array.Copy(buffer, 0, temp, 0, length);
//lstReceive.Invoke(new Action(() =>
//{
// lstReceive.Items.Add(Encoding.UTF8.GetString(temp));
//}));
// 方法2
string msg = Encoding.Default.GetString(buffer,0,length);
lstReceive.Invoke(new Action(()=> {
lstReceive.Items.Add(msg);
}));
}
}
}
private void btnSend_Click(object sender, EventArgs e)
{
byte[] temp = Encoding.Default.GetBytes(textBox3.Text);
try
{
clientSocket.Send(temp);
}
catch (Exception ex)
{
lstReceive.Items.Add($" 消息发送失败:{ex.Message}");
}
}
server 指定客户端发送信息
csharp
Socket serverSocket = null;
Socket ClientSocket = null;
//List<Socket> listSocket=new List<Socket>();
//存储所有监控的客户端
Dictionary<EndPoint,Socket> clientSocketDic=new Dictionary<EndPoint, Socket> ();
private void btnlisten_Click(object sender, EventArgs e)
{
serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(txtIP.Text);
IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(txtPort.Text));
serverSocket.Bind(endpoint);
//同时监控几个客户端
serverSocket.Listen(10);
Task.Run((Action)ListentConnectSocket);//等价于 Action action=ListentConnectSocket;Task.Run(action);
//方法2
//Thread thd = new Thread(ListentConnectSocket);
//thd.IsBackground = true;
//thd.Start();
}
void ListentConnectSocket()
{
// 死循环
while (true)
{
try
{
ClientSocket = serverSocket.Accept(); //放在UI线程,会阻塞,所以放在另外一个线程
string sendMsg = "恭喜您,服务器连接成功!";
ClientSocket.Send(Encoding.Default.GetBytes(sendMsg));
//客户端IP、端口号
string ClientInfo = ClientSocket.RemoteEndPoint.ToString();
//方法1
//Action<string> action = delegate (string msg)
//{
// lsReceive.Items.Add(msg);
//};
//lsReceive.Invoke(action, ClientInfo);
//方法2 匿名方法
//lsReceive.Invoke((Action<string>)delegate(string msg) {
// lsReceive.Items.Add(msg);
//},ClientInfo);
// 方法3 lamda
lsReceive.Invoke(new Action<string>((msg) =>
{
clientSocketDic.Add(ClientSocket.RemoteEndPoint,ClientSocket);
comboBox1.Items.Add(ClientSocket.RemoteEndPoint);
lsReceive.Items.Add($"{msg} 上线啦");
}), ClientInfo);
}
catch (Exception ex)
{
lsReceive.Invoke(new Action<string>((msg) =>
{
lsReceive.Items.Add(msg);
}), $"发送信息失败;{ex.Message}");
break;
}
//开启接收信息
//方法1
//Thread thr = new Thread(ReceiveClientMsg);
//thr.IsBackground = true;
//thr.Start(ClientSocket);
//方法2
Action<Socket> action = new Action<Socket>(ReceiveClientMsg);
Task.Run(()=>action(ClientSocket));
}
}
private void ReceiveClientMsg(object clientSocket)
{
Socket client = clientSocket as Socket;
while (true)
{
byte[] recBuffer = new byte[1024];
int length = -1;
try
{
//Receive 是阻塞方法
length = client.Receive(recBuffer);
}
catch (Exception ex)
{
//客户端关闭应用程序
string str = client.RemoteEndPoint.ToString();
this.Invoke(new Action(() =>
{
lsReceive.Items.Add($"接收客户端:{str} 异常; {ex.Message}");
}));
break;
}
if (length == 0)
{
string str = client.RemoteEndPoint.ToString();
this.Invoke(new Action(() =>
{
lsReceive.Items.Add($"{str}:下线了!");
}));
break;
}
else
{
string msg = Encoding.Default.GetString(recBuffer, 0, length);
string msgStr = $"{DateTime.Now}【 接收客户端: {client.RemoteEndPoint.ToString()}】--- {msg}";
this.Invoke(new Action(() =>
{
lsReceive.Items.Add(msgStr + Environment.NewLine);
}));
}
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if (comboBox1.Text != string.Empty)
{
string[] str=comboBox1.Text.Split(':');
IPEndPoint endpoint=new IPEndPoint(IPAddress.Parse(str[0]), int.Parse(str[1]));
Socket cltsocket = clientSocketDic[endpoint];
Task.Run(new Action(() => {
cltsocket.Send(Encoding.Default.GetBytes(txtSend.Text));
}));
}
}
如何保证数据接受完整的方式
- 校验 双方协商 每次发信息,以什么符号结尾
- 包头+报文 双方协商 每次发信息,以什么符号、开始 、结尾
- 指令长度
数据获取的方式
- PC缓存区
- C# 操作获取数据
- 缓存区自移动