winform socket基于TCP的服务器与客户端通讯-续集

前言

在这个时候我理解了一个词,叫长连接和短连接
长连接的意思就是说声明一个事件然后打开操作…然后关闭 这就为一个长连接,长连接只有最开始的时候打开结束的时候关闭,中间想发什么数据就发什么 想接收什么数据就接收,
短连接的意思就是每次收或者发都要打开关闭 例如发送 的时候 需要打开发送关闭 打开 接收关闭
长连接和短连接都是分情况使用的
tcp连接就是长连接 但是连接的时间太长没有数据可能系统就会认为这个连接已经断开或者默认帮你断开
所以在长连接中还需要做到心跳机制,周期性发送心跳包,为什么叫心跳包
我觉得可能是因为周期性的而且每个人的心跳也不一样,每个人定义心跳包的内容和周期也不一样
所以就叫做心跳吧
这个在时间空间里面就可以实现了
下来我又用字典socket进行分类
让tcp可以同时接收多端口的数据并且可以选择端口发送数据
在加上之前的心跳机制
每次心跳获取服务器端连接的所有客户端的ip端口
想给谁发送数据 就在发送的数据里面加上ip和端口
在服务器端接收到数据的时候进行处理就完成了 两台客户端,或者多台客户端相互之间通讯的效果了

服务器端最终程序

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;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Server
{
public partial class Server_Form : Form
{
// 负责监听客户端的套接字
Socket socket_TCP = null;
// 负责和客户端通信的套接字
Socket socket_Communication = null;
//监听线程
Thread thread_Listen = null;
//客户端 端口号集合
Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
public Server_Form()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void button_Connection_Click(object sender, EventArgs e)
{
if (button_Connection.Text == "连接")
{
button_Connection.Text = "断开";
socket_TCP = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(textBox_IP.Text), (int)numericUpDown_Port.Value);
socket_TCP.Bind(iPEndPoint);
socket_TCP.Listen(0);
thread_Listen = new Thread(TCP_Listen);
thread_Listen.IsBackground = true;
thread_Listen.Start();
}
else if (button_Connection.Text == "断开")
{
button_Connection.Text = "连接";
if (socket_Communication != null)
{
socket_Communication.Close();
}
}
}
private void TCP_Listen()
{
while (true)
{
try
{
socket_Communication = socket_TCP.Accept();
//客户端网络节点
string RemoteEndPoint = socket_Communication.RemoteEndPoint.ToString();
dic.Add(RemoteEndPoint, socket_Communication);
listBoxOnlineList.Items.Add(RemoteEndPoint);
//传参的线程
ParameterizedThreadStart pts = new ParameterizedThreadStart(TCP_Read);
Thread thread = new Thread(pts);
thread.IsBackground = true;
thread.Start(socket_Communication);
}
catch (Exception e)
{
break;
}
}
}
private void button_Send_Click(object sender, EventArgs e)
{
if (listBoxOnlineList.SelectedIndex == -1)
{
MessageBox.Show("请选择要发送的客户端!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
else
{
string selectClient = listBoxOnlineList.Text;
TCP_Write(textBox_Send.Text, selectClient);
textBox_Send.Text = "";
}
}
private void TCP_Write(string data, string EndPoint)
{
try
{
dic[EndPoint].Send(Encoding.UTF8.GetBytes(data));
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return;
}
}
private void TCP_Read(object socket_Read)
{
Socket socket = socket_Read as Socket;
while (true)
{
try
{
byte[] buffer_Data = new byte[1024 * 1024];
int Accept_length = socket.Receive(buffer_Data);
EndPoint endPoint = socket.RemoteEndPoint;
string Str_Data = Encoding.UTF8.GetString(buffer_Data, 0, buffer_Data.Length).Trim("\0".ToCharArray());
if (Str_Data.Substring(0,2) == "aa" && Str_Data.Substring(Str_Data.Length - 2, 2) == "AA")
{
switch (Str_Data.Substring(2,2))
{
case "00":
string str = null;
foreach (var item in dic)
{
str += item.Key + " ";
}
TCP_Write(str, endPoint.ToString());
break;
case "01":
TCP_Write(Str_Data.Substring(19, Str_Data.Length - 21), Str_Data.Substring(4, 15));
break;
default:
break;
}
}
else
{
richTextBox_Receive.AppendText("客户端 " + endPoint + ":" + Str_Data + "\r\n");
}
}
catch (Exception)
{
//提示套接字监听异常
richTextBox_Receive.AppendText("客户端" + socket.RemoteEndPoint + "已经中断连接" + "\r\n");
//移除断开的客户端
dic.Remove(socket.RemoteEndPoint.ToString());
//从listbox中移除断开连接的客户端
listBoxOnlineList.Items.Remove(socket.RemoteEndPoint.ToString());
//关闭之前accept出来的和客户端进行通信的套接字
socket_Communication.Close();
break;
}
}
}
}
}

客户端最终程序

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;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Winform_Chat
{
public partial class Main_Form : Form
{
public Main_Form()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
// 创建一个TCP客户端套接字
Socket Socket_TCP = null;
// 创建一个接收
Thread thread_TCP_Read = null;
private void button_Connection_Click(object sender, EventArgs e)
{
if (button_Connection.Text == "连接")
{
// 定义一个套接字用于监听客户端发来的消息,包含三个参数(ipv4寻址协议,流式连接,tcp协议)
Socket_TCP = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(textBox_IP.Text), (int)numericUpDown_Port.Value);
try
{
Socket_TCP.Connect(iPEndPoint);
}
catch (Exception a)
{
richTextBox_Receive.AppendText(a.Message + "\r\n");
return;
}
timer_Heartbeat.Start();
button_Connection.Text = "关闭";
thread_TCP_Read = new Thread(TCP_Read);
thread_TCP_Read.IsBackground = true;
thread_TCP_Read.Start();
}
else if (button_Connection.Text == "关闭")
{
button_Connection.Text = "连接";
timer_Heartbeat.Stop();
Socket_TCP.Close();
}
}
private void button_Send_Click(object sender, EventArgs e)
{
string str_data = "aa01" + label3.Text + textBox_Send.Text.Trim() + "AA";
Socket_TCP.Send(Encoding.UTF8.GetBytes(str_data));
richTextBox_Receive.AppendText("本机:" + textBox_Send.Text.Trim() + "\r\n");
textBox_Send.Clear();
}
private void TCP_Read()
{
while (true)
{
try
{
byte[] buffer_Data = new byte[1024 * 1024];
int Accept_length = Socket_TCP.Receive(buffer_Data);
if (Accept_length > 0)
{
string Str_Data = Encoding.UTF8.GetString(buffer_Data, 0, buffer_Data.Length).Trim("\0".ToCharArray());
if (Str_Data.IndexOf(":") > 0)
{
listBox_Friends.Items.Clear();
string[] strData = Str_Data.Split(' ');
for (int i = 0; i < strData.Length - 1; i++)
{
listBox_Friends.Items.Add(strData[i]);
}
}
else
{
richTextBox_Receive.AppendText("服务器:" + label3.Text + Str_Data + "\r\n");
}
}
}
catch (Exception e)
{
richTextBox_Receive.AppendText(e.Message + "\r\n");
return;
}
}
}

private void timer_Heartbeat_Tick(object sender, EventArgs e)
{
try
{
string str_IP = "aa00aaAA";
Socket_TCP.Send(Encoding.UTF8.GetBytes(str_IP));
}
catch (Exception)
{
richTextBox_Receive.AppendText("服务器已关闭\r\n");
button_Connection.Text = "连接";
timer_Heartbeat.Stop();
Socket_TCP.Close();
}

}

private void listBox_Friends_SelectedIndexChanged(object sender, EventArgs e)
{
label3.Text = listBox_Friends.SelectedItem.ToString();
}
}
}

效果展示


总结

链接:https://pan.baidu.com/s/1XJ6ilnd9f_syx6NZfQiJZQ
提取码:m4rd

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值