一.几个注意点
1.不允许跨线程访问
private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; }//在窗口加载时加上 `
2. 多线程的使用
hread th1 = new Thread(Resive); th1.Start(s); th1.IsBackground = true; //变为后台线程 主线程结束时一块结束
3.一个 服务器上的 端口 只有一个负责监听的socket 但每连一个客户端就会有一个 负责通信的socket生成
4.转换成ip地址的时候千万别有空格
二.要实现的功能
客户端连接服务器的ip地址与一个应用程序的端口号 ,互发信息
三.
步骤 服务器的配置
namespace WindowsFormsApp1 { public partial class Form1 : Form { Dictionary<string, Socket> dictoryso = new Dictionary<string, Socket>(); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //创建负责监听的 socket Socket so = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//必须ipv4荔浦 //创建ip地址和端口类对象 string s = txtServer.Text; IPAddress ip = IPAddress.Parse(s); IPEndPoint ioend = new IPEndPoint(ip, int.Parse(txtPort.Text)); //让负责监听的socket绑定端口号 so.Bind(ioend);//监听他 show("监听成功"); so.Listen(10);//设置能连接 这个服务器应用程序的最大数量 Thread th = new Thread(Listen); th.IsBackground = true;// th.Start(so);//根据里式转换 父类 对象可以由子类赋值 父类也能转换成父类 } Socket s; void Listen(object o) //引用类型 { Socket so = o as Socket; while (true) { try { //让负责 监听的socket 创建一个负责 通信的socket s = so.Accept();// 一直等待客户端的连接 如果没有就一直卡着 //获取连接端的 IP及端口 dictoryso.Add(s.RemoteEndPoint.ToString(), s); comboBox1.Items.Add(s.RemoteEndPoint.ToString()); show(s.RemoteEndPoint.ToString());//只要有连接就会 show出来继续执行,如果没有 就停在show //接收信息 Thread th1 = new Thread(Resive); th1.Start(s); th1.IsBackground = true; } catch { } } } private void Resive(object s1) { while (true) { try// 防止出异常 { Socket s = (Socket)s1; byte[] buffer = new byte[1024 * 1024 * 2]; //只能传二进制 之后再解码 int r = s.Receive(buffer);//把接收的字节放到buffer 里面 并且 返回 字节数 if (r == 0) break; string str = Encoding.UTF8.GetString(buffer, 0, r); // 解码 txtLog.Clear(); txtLog.Text=str; } catch //什么都不用写 出异常只需 不想下执行 ,不用告诉用户 { } } } private void show(string s) { txtLog.AppendText(s); } private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; } private void txtServer_TextChanged(object sender, EventArgs e) { } private void button2_Click(object sender, EventArgs e) { string str = txtMsg.Text; byte[] buffer = Encoding.UTF8.GetBytes(str); string ip = comboBox1.SelectedItem.ToString(); dictoryso[ip].Send(buffer);// 一个 监听的生成几个 通信的每一个都有一个socket 发信息要用通信的socket } } }
客户端的配置
namespace WindowsFormsApp2 { public partial class Form1 : Form { Socket socketsend; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { socketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ip = IPAddress.Parse(textSever.Text); IPEndPoint point = new IPEndPoint(ip, int.Parse(textPort.Text)); socketsend.Connect(point);//如果不能连接 就一直卡在这里 Showmsg("连接成功"); Thread th = new Thread(Resive); th.Start(); } private void button2_Click(object sender, EventArgs e)//发送消息 { string str = textMsg.Text; byte[] buffer = new byte[1024 * 1024]; buffer = Encoding.UTF8.GetBytes(str); socketsend.Send(buffer); } private void textSever_TextChanged(object sender, EventArgs e) { } private void textPort_TextChanged(object sender, EventArgs e) { } private void Showmsg(string str) { textMsg.AppendText(str); } private void Form1_Load(object sender, EventArgs e) { Control.CheckForIllegalCrossThreadCalls = false; } private void Resive() //接收消息 { while (true) { byte[] buffer = new byte[1024 * 1024]; int r = socketsend.Receive(buffer);//得到后放在 buffer里面 string str = Encoding.UTF8.GetString(buffer,0,r);//解开buffer里面的码// 不写默认全解码 textMsg.Text = str; } } } }
原文:https://www.cnblogs.com/pursuit-purity/p/14633898.html