【C#-Socket监听消息处理】
2016-04-28 11:21
579 查看
TCP/IP:Transmission Control Protocol/Internet Protocol,传输控制协议/因特网互联协议,又名网络通讯协议。简单来说:TCP控制传输数据,负责发现传输的问题,一旦有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地,而IP是负责给因特网中的每一台电脑定义一个地址,以便传输。TCP协议在许多分布式应用程序中进行消息命令传递是必不可少的部分。
TCP通信的三次握手:三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
第一次握手:客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。
第二次握手:服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即X+1。
第三次握手:客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1
先看下服务端Socket监听代码:
下面看下客户端的Socket客户端主动请求服务端代码:
TCP通信的三次握手:三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
第一次握手:客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。
第二次握手:服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即X+1。
第三次握手:客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1
先看下服务端Socket监听代码:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace SocketDome { /// <summary> /// 处理Socket监听逻辑 /// </summary> public class SocketProvider { private static Socket serviceSocketListener; //Socke监听处理请求 /// <summary> /// 开启Socket监听 /// </summary> public static void Init() { serviceSocketListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); serviceSocketListener.Bind(new IPEndPoint(IPAddress.Parse("10.0.0.217"), 20000)); //IP和端口应该是可配置 serviceSocketListener.Listen(1024); Thread handleSocket = new Thread(new ThreadStart(HandleSocket)); handleSocket.Start(); } /// <summary> /// 监听链接 /// </summary> private static void HandleSocket() { while (true) { try { Socket currSocket = serviceSocketListener.Accept(); //为新建连接创建新的 System.Net.Sockets.Socket Thread processThread = new Thread(new ParameterizedThreadStart(ProcessSocket)); processThread.Start(currSocket); } catch { } } } /// <summary> /// 处理Socket信息 /// </summary> /// <param name="obj">新建连接创建新Socket对象</param> private static void ProcessSocket(object obj) { Socket currSocket = (Socket)obj; try { byte[] recvBytess = new byte[1048576]; int recbytes; recbytes = currSocket.Receive(recvBytess, recvBytess.Length, 0); if (recbytes > 0) { var contentStr = Encoding.UTF8.GetString(recvBytess, 0, recbytes); var _order = contentStr.Split('~'); byte[] sendPass = Encoding.UTF8.GetBytes(_order[0].ToUpper() + "#SUCCESS"); //先相应对话,然后去异步处理 currSocket.Send(sendPass, sendPass.Length, SocketFlags.None); switch (_order[0].ToUpper()) { case"ADDCACHE": Console.WriteLine("添加缓存消息" + _order[1]); //处理ADDCACHE逻辑 Console.WriteLine("写Log日志"); break; default : Console.WriteLine("命令错误"); Console.WriteLine("写Log日志"); break; } } } catch (Exception ex) { Console.WriteLine("写Error日志" + ex.Message); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SocketDome { class Program { static void Main(string[] args) { //开启Socket监听处理 SocketProvider.Init(); } } }这个服务端,监听着客户端发来的命令,格式定义为:命令~参数,在服务端接受到客户端的命令消息后立即回传接到命令并开始处理,进行异步处理避免客户端等待。
下面看下客户端的Socket客户端主动请求服务端代码:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; namespace ConsoleApplication7 { /// <summary> /// Socket Helper /// </summary> public class SocketHelper { private string ip; private IPEndPoint ex; private Socket socket; public SocketHelper(string ip, int port) { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); this.ip = ip; this.ex = new IPEndPoint(IPAddress.Parse(ip), port); } /// <summary> /// Socket 进行连接 /// </summary> /// <returns>连接失败OR成功</returns> public bool Socketlink() { try { socket.Connect(ex); return true; } catch (Exception ex) { return false; } } /// <summary> /// Socket 发送消息 /// </summary> /// <param name="strmsg">消息</param> public void SendVarMessage(string strmsg) { try { byte[] msg = System.Text.Encoding.UTF8.GetBytes(strmsg); this.socket.Send(msg); } catch (Exception ex) { this.socket.Close(); } } /// <summary> /// Socket 消息回传 /// </summary> /// <returns></returns> public string ReceiveMessage() { try { byte[] msg = new byte[1048576]; int recv = socket.Receive(msg); this.socket.Close(); return System.Text.Encoding.UTF8.GetString(msg, 0, recv); } catch (Exception ex) { this.socket.Close(); return "ERROR"; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication7 { class Program { static void Main(string[] args) { SocketHelper socket = new SocketHelper("10.0.0.217",20000); if(socket.Socketlink()) { Console.WriteLine("连接成功"); socket.SendVarMessage("ADDCACHE~张三"); string strReposon = socket.ReceiveMessage(); Console.WriteLine(strReposon); } Console.Read(); } } }首先以管理园身份开启服务端查询,然后客户端主动请求服务端进行消息请求。
相关文章推荐
- C# treeview 绑定数据 【转】
- C# 编译报错:“Csc.exe”已退出,代码为 -1073741515
- 【转】C#综合揭秘——通过修改注册表建立Windows自定义协议
- C#虚函数
- C# WebApi 上传文件
- 如何查看.Net源代码vs版本号以及C#项目中各文件的含义
- C#获取本地或远程磁盘使用信息
- C# 读取本地图片
- C#中的设计模式
- C# MVC模式下商品抽奖
- C#窗体应用程度,退出按钮的程序书写
- C#(二)
- (三)C# winform C/S WebBrowser 微博第三方授权登录
- C#发送post请求支持发送文件
- C#编写的基于VLC的播放器
- C#一颗简单多叉树的实现(原理、广度优先遍历、深度优先遍历)
- C#中is和as两种关系运算符
- C# 实现一个窗体调用另一个窗体的控件
- 四.流程控制-学习笔记
- 第 6章 函数