C# winfroms使用socket客户端服务端代码详解

文章目录

  • 1️⃣ 通信相关说明
    • 1.1服务端与客户端
    • 1.2 信息发送原理
    • 1.3 信息接收原理
  • 2️⃣ socket代码
    • 2.1 客户端代码
    • 2.2 服务端代码
  • 3️⃣ 定时任务处理报文
    • 3.1 Timers定时任务
  • 优质资源分享

作者:xcLeigh
文章地址:https://blog.csdn.net/weixin_43151418/article/details/136257608


C# winfroms使用socket客户端服务端代码详解,声明Socket 第一个参数:寻址方式,第二个参数:传输数据的方式,第三个参数:通信协议Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 开启侦听 参数是指可以连接的客户端数量socket.Listen(10);,socket.Accept();这里需要注意,Accept()会阻塞线程,直到连接上客户端。如果放在主线程中,会阻塞前台操作。需要创建一个新的线程。Accept()返回一个socket,客户端连接上之后,服务端自动生成一个socket和连接的客端通信。连接成功后,向客户端发送“连接成功!”

1️⃣ 通信相关说明

1.1服务端与客户端

    启动服务端后,服务端通过持续监听客户端发来的请求,一旦监听到客户端传来的信息(请求),两端便可以互发信息了.
服务端需要绑定一个IP,用于客户端在网络中寻找并建立连接(支持局域网内部客户端与服务端之间的互相通信)

1.2 信息发送原理

    将手动输入字符串信息转换成机器可以识别的字节数组,然后调用套接字的Send()方法将字节数组发送出去

1.3 信息接收原理

    调用套接字的Receive()方法,获取对端传来的字节数组,然后将其转换成人可以读懂的字符串信息

2️⃣ socket代码

2.1 客户端代码

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 TcpMsgClient
{public partial class FrmClient : Form{public FrmClient(){InitializeComponent();//关闭对文本框的非法线程操作检查TextBox.CheckForIllegalCrossThreadCalls = false;}//创建 1个客户端套接字 和1个负责监听服务端请求的线程Socket socketClient = null;Thread threadClient = null;/// <summary>/// 连接服务端事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnListenServer_Click(object sender, EventArgs e){//定义一个套字节监听  包含3个参数(IP4寻址协议,流式连接,TCP协议)socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//需要获取文本框中的IP地址IPAddress ipaddress = IPAddress.Parse(this.txtIP.Text.Trim());//将获取的ip地址和端口号绑定到网络节点endpoint上IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(this.txtPort.Text.Trim()));//这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bindtry{socketClient.Connect(endpoint);this.txtMsg.AppendText("客户端连接服务端成功!" + "\r\n");this.btnListenServer.Enabled = false;//创建一个线程 用于监听服务端发来的消息threadClient = new Thread(RecMsg);//将窗体线程设置为与后台同步threadClient.IsBackground = true;//启动线程threadClient.Start();}catch (Exception ex) {this.txtMsg.AppendText("远程服务端断开,连接失败!" + "\r\n");}}/// <summary>/// 接收服务端发来信息的方法/// </summary>private void RecMsg(){while (true) //持续监听服务端发来的消息{try{//定义一个1M的内存缓冲区 用于临时性存储接收到的信息byte[] arrRecMsg = new byte[1024 * 1024];//将客户端套接字接收到的数据存入内存缓冲区, 并获取其长度int length = socketClient.Receive(arrRecMsg);//将套接字获取到的字节数组转换为人可以看懂的字符串string strRecMsg = Encoding.UTF8.GetString(arrRecMsg, 0, length);//将发送的信息追加到聊天内容文本框中txtMsg.AppendText("服务端 " + GetCurrentTime() + "\r\n" + strRecMsg + "\r\n");}catch (Exception ex) {this.txtMsg.AppendText("远程服务器已中断连接!"+"\r\n");this.btnListenServer.Enabled = true;break;}}}/// <summary>/// 发送字符串信息到服务端的方法/// </summary>/// <param name="sendMsg">发送的字符串信息</param>private void ClientSendMsg(string sendMsg){try {//将输入的内容字符串转换为机器可以识别的字节数组byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);//调用客户端套接字发送字节数组socketClient.Send(arrClientSendMsg);//将发送的信息追加到聊天内容文本框中txtMsg.AppendText("天涯 " + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");}catch(Exception ex){this.txtMsg.AppendText("远程服务器已中断连接,无法发送消息!" + "\r\n");}}private void btnSendMsg_Click(object sender, EventArgs e){//调用ClientSendMsg方法 将文本框中输入的信息发送给服务端ClientSendMsg(this.txtClientSendMsg.Text.Trim());this.txtClientSendMsg.Clear();}private void txtClientSendMsg_KeyDown(object sender, KeyEventArgs e){//当光标位于文本框时 如果用户按下了键盘上的Enter键if (e.KeyCode == Keys.Enter){//则调用客户端向服务端发送信息的方法ClientSendMsg(this.txtClientSendMsg.Text.Trim());this.txtClientSendMsg.Clear();}}/// <summary>/// 获取当前系统时间的方法/// </summary>/// <returns>当前时间</returns>private DateTime GetCurrentTime(){DateTime currentTime = new DateTime();currentTime = DateTime.Now;return currentTime;}}
}

2.2 服务端代码

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 TcpMsgServer
{public partial class FrmServer : Form{public FrmServer(){InitializeComponent();//关闭对文本框的非法线程操作检查TextBox.CheckForIllegalCrossThreadCalls = false;}Thread threadWatch = null; //负责监听客户端的线程Socket socketWatch = null;  //负责监听客户端的套接字/// <summary>/// 启动服务/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnServerConn_Click(object sender, EventArgs e){try{//定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//服务端发送信息 需要1个IP地址和端口号IPAddress ipaddress = IPAddress.Parse(this.txtIP.Text.Trim()); //获取文本框输入的IP地址//将IP地址和端口号绑定到网络节点endpoint上IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(this.txtPort.Text.Trim())); //获取文本框上输入的端口号//监听绑定的网络节点socketWatch.Bind(endpoint);//将套接字的监听队列长度限制为20socketWatch.Listen(20);//创建一个监听线程threadWatch = new Thread(WatchConnecting);//将窗体线程设置为与后台同步threadWatch.IsBackground = true;//启动线程threadWatch.Start();//启动线程后 txtMsg文本框显示相应提示txtMsg.AppendText("开始监听客户端传来的信息!" + "\r\n");this.btnServerConn.Enabled = false;}catch (Exception ex) {txtMsg.AppendText("服务端启动服务失败!" + "\r\n");this.btnServerConn.Enabled = true;}}//创建一个负责和客户端通信的套接字Socket socConnection = null;/// <summary>/// 监听客户端发来的请求/// </summary>private void WatchConnecting(){while (true)  //持续不断监听客户端发来的请求{socConnection = socketWatch.Accept();txtMsg.AppendText("客户端连接成功! " + "\r\n");//创建一个通信线程ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);Thread thr = new Thread(pts);thr.IsBackground = true;//启动线程thr.Start(socConnection);}}/// <summary>/// 发送信息到客户端的方法/// </summary>/// <param name="sendMsg">发送的字符串信息</param>private void ServerSendMsg(string sendMsg){try{//将输入的字符串转换成 机器可以识别的字节数组byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendMsg);//向客户端发送字节数组信息socConnection.Send(arrSendMsg);//将发送的字符串信息附加到文本框txtMsg上txtMsg.AppendText("服务器 " + GetCurrentTime() + "\r\n" + sendMsg + "\r\n");}catch (Exception ex) {txtMsg.AppendText("客户端已断开连接,无法发送信息!" + "\r\n");}}/// <summary>/// 接收客户端发来的信息/// </summary>/// <param name="socketClientPara">客户端套接字对象</param>private void ServerRecMsg(object socketClientPara){Socket socketServer = socketClientPara as Socket;while (true){//创建一个内存缓冲区 其大小为1024*1024字节  即1Mbyte[] arrServerRecMsg = new byte[1024 * 1024];try{//将接收到的信息存入到内存缓冲区,并返回其字节数组的长度int length = socketServer.Receive(arrServerRecMsg);//将机器接受到的字节数组转换为人可以读懂的字符串string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);//将发送的字符串信息附加到文本框txtMsg上txtMsg.AppendText("天涯 " + GetCurrentTime() + "\r\n" + strSRecMsg + "\r\n");}catch (Exception ex) {txtMsg.AppendText("客户端已断开连接!" + "\r\n");break;}}}/// <summary>/// 发送消息到客户端/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSendMsg_Click(object sender, EventArgs e){//调用 ServerSendMsg方法  发送信息到客户端ServerSendMsg(this.txtSendMsg.Text.Trim());this.txtSendMsg.Clear();}/// <summary>/// 快捷键 Enter 发送信息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void txtSendMsg_KeyDown(object sender, KeyEventArgs e){//如果用户按下了Enter键if (e.KeyCode == Keys.Enter){//则调用 服务器向客户端发送信息的方法ServerSendMsg(txtSendMsg.Text.Trim());this.txtSendMsg.Clear();}}/// <summary>/// 获取当前系统时间的方法/// </summary>/// <returns>当前时间</returns>private DateTime GetCurrentTime(){DateTime currentTime = new DateTime();currentTime = DateTime.Now;return currentTime;}/// <summary>/// 获取本地IPv4地址/// </summary>/// <returns></returns>public IPAddress GetLocalIPv4Address() {IPAddress localIpv4 = null;//获取本机所有的IP地址列表IPAddress[] IpList = Dns.GetHostAddresses(Dns.GetHostName());//循环遍历所有IP地址foreach (IPAddress IP in IpList) {//判断是否是IPv4地址if (IP.AddressFamily == AddressFamily.InterNetwork){localIpv4 = IP;}else {continue;}}return localIpv4;}/// <summary>/// 获取本地IP事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnGetLocalIP_Click(object sender, EventArgs e){//接收IPv4的地址IPAddress localIP = GetLocalIPv4Address();//赋值给文本框this.txtIP.Text = localIP.ToString();}}
}

3️⃣ 定时任务处理报文

3.1 Timers定时任务

    在内部多线程情况下,这个定时任务,支持,启动,设定条件,满足后执行任务,不满做执行设定任务,然后自动销毁。

using SimulateMaster.Bean;
using SimulateMaster.page;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;namespace SimulateMaster.Util
{public class MsgReply{private ServiceMain _serviceMain;private readonly System.Timers.Timer _timer;public static string clicentInfo_value = ""; //设备信息【IP:端口】public static string mainName_value=""; //窗体名称public static string msgContent= MsgUtils.MSG_QDLL;//报文内容public int msgNum=0;//重发次数 最多三次public MsgReply(string msgValue,string clientInfo,string mainName, ServiceMain serviceMain){clicentInfo_value = clientInfo;mainName_value = mainName;_serviceMain = serviceMain;msgContent = msgValue;// 设置定时器间隔(单位为毫秒)_timer = new System.Timers.Timer(5000);// 添加 Elapsed 事件处理程序_timer.Elapsed += OnTimerElapsed;// 开始计时器_timer.Start();}protected virtual void OnTimerElapsed(object sender, ElapsedEventArgs e){FileUtils.WriteFileLog("定时任务触发没有接收到回复报文!", "报文接收定时任务");}public void Dispose(){FileUtils.WriteFileLog(clicentInfo_value + "定时任务关闭!", "报文接收定时任务");if (_timer != null && _timer.Enabled)_timer.Stop();_timer?.Dispose();}}
}
--------------- 业精于勤,荒于嬉 ---------------

请添加图片描述

--------------- 行成于思,毁于随 ---------------

优质资源分享

🧡🧡🧡🧡🤍【总览】程序员前端、后端资源合集

🧡🧡🧡🧡🤍【源码】程序员优质资源汇总

🧡🧡🧡🧡🤍【博主推荐】JAVA SSM框架的后台管理系统(附源码)

🧡🧡🧡🧡🤍【博主推荐】SpringBoot API接口对数据库增删改查,路由,TOKEN,WebSocket完整版(附源码)

🧡🧡🧡🧡🤍【博主推荐】HTML制作一个美观的个人简介网页(附源码)

🧡🧡🧡🧡🤍【博主推荐】html好看的个人简历网页版(附源码)

🧡🧡🧡🧡🤍【博主推荐】html好看的个人主页(附源码)

🧡🧡🧡🧡🤍【博主推荐】html好看的邀请函(附源码)

🧡🧡🧡🧡🤍【博主推荐】html好看的音乐播放器(附源码)

🧡🧡🧡🧡🤍【博主推荐】html好看的拼图小游戏(附源码)

🧡🧡🧡🤍🤍【博主推荐】html好看的拼图验证码(附源码)

🧡🧡🧡🧡🧡【博主推荐】html界面绘制SVG图形(附源码)

🧡🧡🧡🧡🤍【博主推荐】html操作SVG图(附源码)

🧡🧡🧡🧡🤍【博主推荐】html下拉框树形(附好看的登录界面)

🧡🧡🧡🧡🤍【博主推荐】HTML5响应式手机WEB(附源码)

🧡🧡🧡🧡🤍【博主推荐】大数据可视化大屏(源码下载)

🧡🧡🧡🧡🧡【博主推荐】html引用百度地图定位闪烁弹框树形(附源码)

🧡🧡🧡🧡🤍【博主推荐】HTML酷炫动画表白求爱界面(附源码)


请添加图片描述


     💞 关注博主 带你实现畅游前后端

     🏰 加入社区 带你体验马航不孤单

     💯 神秘个人简介 带你体验不一样得介绍

     🎀 酷炫邀请函 带你体验高大上得邀请


     ① 🉑提供云服务部署(有自己的阿里云);
     ② 🉑提供前端、后端、应用程序、H5、小程序、公众号等相关业务;
     如🈶合作请联系我,期待您的联系。
    :本文撰写于CSDN平台,作者:xcLeigh所有权归作者所有) ,https://blog.csdn.net/weixin_43151418,如果相关下载没有跳转,请查看这个地址,相关链接没有跳转,皆是抄袭本文,转载请备注本文原地址。


     亲,码字不易,动动小手,欢迎 点赞 ➕ 收藏,如 🈶 问题请留言(评论),博主看见后一定及时给您答复,💌💌💌


原文地址:https://blog.csdn.net/weixin_43151418/article/details/136257608(防止抄袭,原文地址不可删除)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2804752.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【扩散模型】【网络结构探索】神经网络扩散:Neural Network Diffusion(论文解读)

项目地址&#xff1a;https://github.com/NUS-HPC-AI-Lab/Neural-Network-Diffusion 文章目录 摘要一、前言二、Nerual Network Diffusion &#xff08;神经网络扩散&#xff09;2.1扩散模型&#xff08;预备知识&#xff09;2.2 总览2.3 参数自动编码器2.4 参数生成 三、实验3…

RocketMQ快速实战以及集群架构原理详解

RocketMQ快速实战以及集群架构原理详解 组成部分 启动Rocket服务之前要先启动NameServer NameServer 提供轻量级Broker路由服务&#xff0c;主要是提供服务注册 Broker 实际处理消息存储、转发等服务的核心组件 Producer 消息生产者集群&#xff0c;通常为业务系统中的一个功…

xff注入 [CISCN2019 华东南赛区]Web111

打开题目 看见smarty 想到模板注入 又看见ip 想到xff注入 一般情况下输入{$smarty.version}就可以看到返回的smarty的版本号。该题目的Smarty版本是3.1.30 在Smarty3的官方手册里有以下描述: Smarty已经废弃{php}标签&#xff0c;强烈建议不要使用。在Smarty 3.1&#xff…

07 MyBatis之高级映射 + 懒加载(延迟加载)+缓存

1. 高级映射 例如有两张表, 分别为班级表和学生表 自然, 一个班级对应多个学生 像这种数据 , 应该如果如何映射到Java的实体类上呢? 这就是高级映射解决的问题 以班级和学生为例子 , 因为一个班级对应多个学生 , 因此学生表中必定有一个班级编号字段cid 但我们在学生的实体…

HarmonyOS学习--三方库

文章目录 一、三方库获取二、常用的三方库1. UI库&#xff1a;2. 网络库&#xff1a;3. 动画库&#xff1a; 三、使用开源三方库1. 安装与卸载2. 使用 四、问题解决1. zsh: command not found: ohpm 一、三方库获取 在Gitee网站中获取 搜索OpenHarmony-TPC仓库&#xff0c;在t…

Day20_网络编程(软件结构,网络编程三要素,UDP网络编程,TCP网络编程)

文章目录 Day20 网络编程学习目标1 软件结构2 网络编程三要素2.1 IP地址和域名1、IP地址2、域名3、InetAddress类 2.2 端口号2.3 网络通信协议1、OSI参考模型和TCP/IP参考模型2、UDP协议3、TCP协议 2.4 Socket编程 3 UDP网络编程3.1 DatagramSocket和DatagramPacket1、Datagram…

强大的文本绘图——PlantUML

PlantUML是一款开源工具&#xff0c;它允许用户通过简单的文本描述来创建UML图&#xff08;统一建模语言图&#xff09;。这种方法可以快速地绘制类图、用例图、序列图、状态图、活动图、组件图和部署图等UML图表。PlantUML使用一种领域特定语言&#xff08;DSL&#xff09;&am…

PostMan使用自带js库base64编码、sha256摘要、环境变量的使用

目录 1、环境变量的使用2、base64编码、sha256摘要、以及脚本的使用3、脚本代码 在请求调试接口的过程中&#xff0c;因为要使用大量相同的参数&#xff0c;使用变量的方式能很大程度上减轻接口调用的工作量 版本说明&#xff1a;Postman for Windows&#xff0c;Version&#…

BUGKU-WEB 备份是个好习惯

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; 解题思路 看源码看提示&#xff1a;备份是个好习惯扫描目录md5弱比较 相关工具 御剑md5解密&#xff1a;https://www.somd5.com/ 解题步骤 看到的这串字符&#xff0c;有点像md5&#xff1f; d41d8cd98…

【PCL】(十二)使用ConditionalRemoval或RadiusOutlierRemoval滤波器对点云进行滤波

&#xff08;十二&#xff09;使用ConditionalRemoval 或 RadiusOutlierRemoval滤波器对点云进行滤波 RadiusOutlierRemove滤波器删除PointCloud中在指定半径的邻域范内&#xff0c;邻点没能达到指定数量的点。下图中&#xff0c;如果指定了邻点数为1&#xff0c;则黄色点将从…

亿道丨三防平板电脑厂家推荐丨三防平板PAN智能化赋能

随着科技的不断进步和人们对智能化产品的需求日益增长&#xff0c;三防平板迎来了智能化赋能的时代。通过融合创新科技&#xff0c;三防平板实现了更高的性能、更智能的功能以及更广泛的应用场景&#xff0c;引领着未来的发展潮流。 一、智能化技术提升性能 随着技术的进步&…

Nginx网络服务四-----日志、Nginx压缩和ssl

1.自定义访问日志 如果访问出错---404&#xff0c;可以去看error.log日志信息 访问日志是记录客户端即用户的具体请求内容信息&#xff0c;而在全局配置模块中的error_log是记录nginx服务器运行时的日志保存路径和记录日志的level&#xff0c;因此两者是不同的&#xff0c;而且…

openssl 生成nginx自签名的证书

1、命令介绍 openssl req命令主要的功能有&#xff0c;生成证书请求文件&#xff0c; 查看验证证书请求文件&#xff0c;还有就是生成自签名证书。 主要参数 主要命令选项&#xff1a; -new :说明生成证书请求文件 -x509 :说明生成自签名证书 -key :指定已…

计算机网络面经-从浏览器地址栏输入 url 到显示主页的过程?

大概的过程比较简单&#xff0c;但是有很多点可以细挖&#xff1a;DNS解析、TCP三次握手、HTTP报文格式、TCP四次挥手等等。 DNS 解析&#xff1a;将域名解析成对应的 IP 地址。TCP连接&#xff1a;与服务器通过三次握手&#xff0c;建立 TCP 连接向服务器发送 HTTP 请求服务器…

JS基础(一)

一 JS概述 1. 历史 1995年 JS出现在网景浏览器中 1996年 IE也开始出现了JS 1997年 指定了JS的标准规范ECMAScript 目前是ES6 2009年 JS开始向后端发展&#xff0c;出现了Node.js 二 JS入门 1. JS的运行方式 1. 内部写法 <script>J…

查看navicat保存的数据库连接密码

背景 经常使用navicat的朋友可能会碰到忘记数据库连接密码的情况&#xff0c;自然会想到navicat连接配置中就保存了密码。 个人经验&#xff0c;按以下步骤可查看密码明文 本人在mac上使用的navicat版本 1&#xff0c;导出connection_local.ncx 点击OK导出保存为connection_l…

iOS面试:4.多线程GCD

一、多线程基础知识 1.1 什么是进程&#xff1f; 进程是指在系统中正在运行的一个应用程序。对于电脑而已&#xff0c;你打开一个软件&#xff0c;就相当于开启了一个进程。对于手机而已&#xff0c;你打开了一个APP&#xff0c;就相当于开启了一个进程。 1.2 什么是线程&am…

【电子书】人工智能

资料 wx&#xff1a;1945423050&#xff0c;备注来源和目的 个人整理了一些互联网电子书 人工智能 Julia机器学习核心编程&#xff1a;人人可用的高性能科学计算.epubKeras深度学习实战.epubMATLAB图像与视频处理实用案例详解.epubMATLAB金融算法分析实战&#xff1a;基于机器…

Java学习笔记2024/2/23

今日内容 抽象类 接口 内部类 教学目标 能够写出抽象类的格式能够写出抽象方法的格式能说出抽象类的应用场景写出定义接口的格式写出实现接口的格式说出接口中成员的特点能说出接口的应用场景能说出接口中为什么会出现带有方法体的方法能完成适配器设计模式 第一章 抽象类…

c语言--typedef关键字

目录 一、typedef关键字是用来干嘛的&#xff1f;二、用法 一、typedef关键字是用来干嘛的&#xff1f; typedef 是⽤来类型重命名的&#xff0c;可以将复杂的类型&#xff0c;简单化。 二、用法 比如&#xff0c;你觉得 unsigned int 写起来不方便&#xff0c;如果能写成 u…