简单的Socket通信(简单的在线聊天)---winform
注:本博客适合刚开始学习winform程序的初学者,大牛请绕道(跪求大牛指导文中不足)
.....10w字废话自动省略,直接开始正题.
首先从最基本的建立winform开始(本项目用的vs2017)
新建->项目->选中c#->选择windows窗体应用->确定
创建完成后可以点击工具栏进行拖拽控件 ,双击控件进入事件的逻辑处理,右击鼠标选择属性进行配置
各属性的作用可参考微软文档 https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.forms.control.accessiblename?view=netframework-4.8
首先展示一下效果图
注:
博主在一台电脑上创建了两个项目,打开两个visualstudio(一个运行服务端,一个运行客户端),
由于socked端口占用问题,
服务端和客户端运行起来后,
客户端ip输入自己电脑的ip->端口port随便输入->点击连接,提示连接成功。例:ip:192.168.1.129 port:80
服务端ip输入自己电脑ip->端口port随便输入--->点击开始监听,提示监听成功。例:ip:192.168.1.129 port:81
客户端ip输入自己电脑ip->端口port输入服务端端口号->点击连接,提示连接成功可以开始发送消息:例:ip:192.168.1.129 port:81
(从上到下按顺序执行)
以上操作是因为服务端、客户端在同一台电脑上,造成端口占用, 如果服务端和客户端分开的话客户端可以直接输入服务端ip和端口连接监听。
接下来贴代码:
服务端
↓↓↓↓↓
↓↓↓
↓↓
↓
designer.cs文件代码 (小白不会设置控件属性的话,可以跳过拖拽控件,直接复制以下代码)
↓↓↓↓↓↓↓
↓↓↓↓
↓↓
↓
namespace mywindows { partial class form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private system.componentmodel.icontainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void dispose(bool disposing) { if (disposing && (components != null)) { components.dispose(); } base.dispose(disposing); } #region windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要修改 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void initializecomponent() { this.panel1 = new system.windows.forms.panel(); this.tb_ip = new system.windows.forms.textbox(); this.lb_ip = new system.windows.forms.label(); this.lb_port = new system.windows.forms.label(); this.tb_port = new system.windows.forms.textbox(); this.bt_connnect = new system.windows.forms.button(); this.listbox1 = new system.windows.forms.listbox(); this.txt_msg = new system.windows.forms.textbox(); this.bt_send = new system.windows.forms.button(); this.panel1.suspendlayout(); this.suspendlayout(); // // panel1 // this.panel1.controls.add(this.bt_connnect); this.panel1.controls.add(this.lb_port); this.panel1.controls.add(this.tb_port); this.panel1.controls.add(this.lb_ip); this.panel1.controls.add(this.tb_ip); this.panel1.location = new system.drawing.point(21, 12); this.panel1.name = "panel1"; this.panel1.size = new system.drawing.size(580, 70); this.panel1.tabindex = 0; // // tb_ip // this.tb_ip.location = new system.drawing.point(44, 18); this.tb_ip.name = "tb_ip"; this.tb_ip.size = new system.drawing.size(100, 21); this.tb_ip.tabindex = 0; this.tb_ip.text = "127.0.0.1"; // // lb_ip // this.lb_ip.autosize = true; this.lb_ip.location = new system.drawing.point(15, 21); this.lb_ip.name = "lb_ip"; this.lb_ip.size = new system.drawing.size(23, 12); this.lb_ip.tabindex = 1; this.lb_ip.text = "ip:"; // // lb_port // this.lb_port.autosize = true; this.lb_port.location = new system.drawing.point(158, 24); this.lb_port.name = "lb_port"; this.lb_port.size = new system.drawing.size(35, 12); this.lb_port.tabindex = 3; this.lb_port.text = "port:"; // // tb_port // this.tb_port.location = new system.drawing.point(199, 21); this.tb_port.name = "tb_port"; this.tb_port.size = new system.drawing.size(100, 21); this.tb_port.tabindex = 2; this.tb_port.text = "80"; // // bt_connnect // this.bt_connnect.location = new system.drawing.point(316, 15); this.bt_connnect.name = "bt_connnect"; this.bt_connnect.size = new system.drawing.size(132, 42); this.bt_connnect.tabindex = 4; this.bt_connnect.text = "开始监听"; this.bt_connnect.usevisualstylebackcolor = true; this.bt_connnect.click += new system.eventhandler(this.bt_connnect_click); // // listbox1 // this.listbox1.formattingenabled = true; this.listbox1.itemheight = 12; this.listbox1.location = new system.drawing.point(21, 112); this.listbox1.name = "listbox1"; this.listbox1.size = new system.drawing.size(580, 124); this.listbox1.tabindex = 1; // // txt_msg // this.txt_msg.location = new system.drawing.point(21, 255); this.txt_msg.multiline = true; this.txt_msg.name = "txt_msg"; this.txt_msg.size = new system.drawing.size(424, 73); this.txt_msg.tabindex = 2; // // bt_send // this.bt_send.location = new system.drawing.point(471, 266); this.bt_send.name = "bt_send"; this.bt_send.size = new system.drawing.size(119, 52); this.bt_send.tabindex = 3; this.bt_send.text = "发送"; this.bt_send.usevisualstylebackcolor = true; this.bt_send.click += new system.eventhandler(this.bt_send_click); // // form1 // this.autoscaledimensions = new system.drawing.sizef(6f, 12f); this.autoscalemode = system.windows.forms.autoscalemode.font; this.clientsize = new system.drawing.size(695, 340); this.controls.add(this.bt_send); this.controls.add(this.txt_msg); this.controls.add(this.listbox1); this.controls.add(this.panel1); this.name = "form1"; this.text = "socketform"; this.load += new system.eventhandler(this.form1_load); this.panel1.resumelayout(false); this.panel1.performlayout(); this.resumelayout(false); this.performlayout(); } #endregion private system.windows.forms.panel panel1; private system.windows.forms.button bt_connnect; private system.windows.forms.label lb_port; private system.windows.forms.textbox tb_port; private system.windows.forms.label lb_ip; private system.windows.forms.textbox tb_ip; private system.windows.forms.listbox listbox1; private system.windows.forms.textbox txt_msg; private system.windows.forms.button bt_send; } }
控件事件逻辑处理 (小白可以随便选中一个控件双击进去, 直接将下面的代码覆盖到项目中)
↓↓↓↓↓↓↓
↓↓↓↓
↓↓
↓
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 mywindows { partial class form1 : form { public form1() { initializecomponent(); } private void bt_connnect_click(object sender, eventargs e) { try { //点击开始监听时 在服务端创建一个负责监听ip和端口号的socket socket socketwatch = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); ipaddress ip = ipaddress.any; //创建对象端口 ipendpoint point = new ipendpoint(ip, convert.toint32(tb_port.text)); socketwatch.bind(point);//绑定端口号 showmsg("监听成功!"); socketwatch.listen(10);//设置监听 //创建监听线程 thread thread = new thread(listen); thread.isbackground = true; thread.start(socketwatch); } catch { } } /// <summary> /// 等待客户端的连接 并且创建与之通信的socket /// </summary> socket socketsend; void listen(object o) { try { socket socketwatch = o as socket; while (true) { socketsend = socketwatch.accept();//等待接收客户端连接 showmsg(socketsend.remoteendpoint.tostring() + ":" + "连接成功!"); //开启一个新线程,执行接收消息方法 thread r_thread = new thread(received); r_thread.isbackground = true; r_thread.start(socketsend); } } catch { } } /// <summary> /// 服务器端不停的接收客户端发来的消息 /// </summary> /// <param name="o"></param> void received(object o) { try { socket socketsend = o as socket; while (true) { //客户端连接服务器成功后,服务器接收客户端发送的消息 byte[] buffer = new byte[1024 * 1024 * 3]; //实际接收到的有效字节数 int len = socketsend.receive(buffer); if (len == 0) { break; } string str = encoding.utf8.getstring(buffer, 0, len); showmsg(socketsend.remoteendpoint + ":" + str); } } catch { } } /// <summary> /// 服务器向客户端发送消息 /// </summary> /// <param name="str"></param> void send(string str) { byte[] buffer = encoding.utf8.getbytes(str); socketsend.send(buffer); } void showmsg(string msg) { listbox1.items.add(msg + "\r\n"); } private void form1_load(object sender, eventargs e) { control.checkforillegalcrossthreadcalls = false; } private void bt_send_click(object sender, eventargs e) { send(txt_msg.text.trim()); } } }
客户端
↓↓↓↓↓↓
↓↓↓
↓↓
↓
namespace myclient { partial class form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private system.componentmodel.icontainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void dispose(bool disposing) { if (disposing && (components != null)) { components.dispose(); } base.dispose(disposing); } #region windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要修改 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void initializecomponent() { this.panel1 = new system.windows.forms.panel(); this.lb_ip = new system.windows.forms.label(); this.txt_ip = new system.windows.forms.textbox(); this.txt_port = new system.windows.forms.textbox(); this.lb_port = new system.windows.forms.label(); this.bt_connect = new system.windows.forms.button(); this.textbox1 = new system.windows.forms.textbox(); this.txt_msg = new system.windows.forms.textbox(); this.bt_send = new system.windows.forms.button(); this.panel1.suspendlayout(); this.suspendlayout(); // // panel1 // this.panel1.controls.add(this.bt_connect); this.panel1.controls.add(this.txt_port); this.panel1.controls.add(this.lb_port); this.panel1.controls.add(this.txt_ip); this.panel1.controls.add(this.lb_ip); this.panel1.location = new system.drawing.point(12, 12); this.panel1.name = "panel1"; this.panel1.size = new system.drawing.size(463, 75); this.panel1.tabindex = 0; // // lb_ip // this.lb_ip.autosize = true; this.lb_ip.location = new system.drawing.point(14, 23); this.lb_ip.name = "lb_ip"; this.lb_ip.size = new system.drawing.size(23, 12); this.lb_ip.tabindex = 0; this.lb_ip.text = "ip:"; // // txt_ip // this.txt_ip.location = new system.drawing.point(43, 20); this.txt_ip.name = "txt_ip"; this.txt_ip.size = new system.drawing.size(100, 21); this.txt_ip.tabindex = 1; this.txt_ip.text = "127.0.0.1"; // // txt_port // this.txt_port.location = new system.drawing.point(207, 23); this.txt_port.name = "txt_port"; this.txt_port.size = new system.drawing.size(100, 21); this.txt_port.tabindex = 3; this.txt_port.text = "2001"; // // lb_port // this.lb_port.autosize = true; this.lb_port.location = new system.drawing.point(166, 29); this.lb_port.name = "lb_port"; this.lb_port.size = new system.drawing.size(35, 12); this.lb_port.tabindex = 2; this.lb_port.text = "port:"; // // bt_connect // this.bt_connect.location = new system.drawing.point(313, 9); this.bt_connect.name = "bt_connect"; this.bt_connect.size = new system.drawing.size(113, 47); this.bt_connect.tabindex = 4; this.bt_connect.text = "连接"; this.bt_connect.usevisualstylebackcolor = true; this.bt_connect.click += new system.eventhandler(this.bt_connect_click); // // textbox1 // this.textbox1.location = new system.drawing.point(12, 103); this.textbox1.multiline = true; this.textbox1.name = "textbox1"; this.textbox1.size = new system.drawing.size(463, 114); this.textbox1.tabindex = 1; // // txt_msg // this.txt_msg.location = new system.drawing.point(12, 246); this.txt_msg.multiline = true; this.txt_msg.name = "txt_msg"; this.txt_msg.size = new system.drawing.size(291, 54); this.txt_msg.tabindex = 2; // // bt_send // this.bt_send.location = new system.drawing.point(325, 246); this.bt_send.name = "bt_send"; this.bt_send.size = new system.drawing.size(113, 54); this.bt_send.tabindex = 3; this.bt_send.text = "发送"; this.bt_send.usevisualstylebackcolor = true; this.bt_send.click += new system.eventhandler(this.bt_send_click); // // form1 // this.autoscaledimensions = new system.drawing.sizef(6f, 12f); this.autoscalemode = system.windows.forms.autoscalemode.font; this.clientsize = new system.drawing.size(493, 323); this.controls.add(this.bt_send); this.controls.add(this.txt_msg); this.controls.add(this.textbox1); this.controls.add(this.panel1); this.name = "form1"; this.text = "form1"; this.load += new system.eventhandler(this.form1_load); this.panel1.resumelayout(false); this.panel1.performlayout(); this.resumelayout(false); this.performlayout(); } #endregion private system.windows.forms.panel panel1; private system.windows.forms.label lb_ip; private system.windows.forms.button bt_connect; private system.windows.forms.textbox txt_port; private system.windows.forms.label lb_port; private system.windows.forms.textbox txt_ip; private system.windows.forms.textbox textbox1; private system.windows.forms.textbox txt_msg; private system.windows.forms.button bt_send; } }
双击控件进入(.cs文件)
↓↓↓↓↓↓↓
↓↓↓↓
↓
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.windows.forms; namespace myclient { public partial class form1 : form { public form1() { initializecomponent(); } socket socketsend; private void bt_connect_click(object sender, eventargs e) { try { //创建客户端socket,获得远程ip和端口号 socketsend = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); ipaddress ip = ipaddress.parse(txt_ip.text); ipendpoint point = new ipendpoint(ip, convert.toint32(txt_port.text)); socketsend.connect(point); showmsg("连接成功!"); //开启新的线程,不停的接收服务器发来的消息 thread c_thread = new thread(received); c_thread.isbackground = true; c_thread.start(); } catch (exception){ showmsg("ip或者端口号错误..."); } } void showmsg(string str) { textbox1.appendtext(str + "\r\n"); } /// <summary> /// 接收服务端返回的消息 /// </summary> void received() { while (true) { try { byte[] buffer = new byte[1024 * 1024 * 3]; //实际接收到的有效字节数 int len = socketsend.receive(buffer); if (len == 0) { break; } string str = encoding.utf8.getstring(buffer, 0, len); showmsg(socketsend.remoteendpoint + ":" + str); } catch { } } } /// <summary> /// 向服务器发送消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void bt_send_click(object sender, eventargs e) { try { string msg = txt_msg.text.trim(); byte[] buffer = new byte[1024 * 1024 * 3]; buffer = encoding.utf8.getbytes(msg); socketsend.send(buffer); } catch { } } private void form1_load(object sender, eventargs e) { control.checkforillegalcrossthreadcalls = false; } } }
socket原理可参考 https://www.cnblogs.com/wangkaining/p/6089627.html
以上代码复制粘贴完成后注意项目命名,可直接运行.有问题评论区探讨.
上一篇: linux线程的取消(终止)方法