C# Socket系列二 简单的创建 socket 通信
看了系列一 我们开启了对socket tcp的监听状态,那么这一章我们来讲解怎么创建socket的通信代码
我新建一个类 TSocketBase
public abstract class TSocketBase { //封装socket internal Socket _Socket; //回调 private AsyncCallback aCallback; //接受数据的缓冲区 private byte[] Buffers; //标识是否已经释放 private volatile bool IsDispose; //10K的缓冲区空间 * ; //收取消息状态码 private SocketError ReceiveError; //发送消息的状态码 private SocketError SenderError; //每一次接受到的字节数 ; //接受空消息次数 ; public abstract void Receive(byte[] rbuff); public void SetSocket() { this.aCallback = new AsyncCallback(this.ReceiveCallback); this.IsDispose = false; this._Socket.ReceiveBufferSize = this.BufferSize; this._Socket.SendBufferSize = this.BufferSize; this.Buffers = new byte[this.BufferSize]; } /// <summary> /// 关闭并释放资源 /// </summary> /// <param name="msg"></param> public void Close(string msg) { if (!this.IsDispose) { this.IsDispose = true; try { try { this._Socket.Close(); } catch { } IDisposable disposable = this._Socket; if (disposable != null) { disposable.Dispose(); } this.Buffers = null; GC.SuppressFinalize(this); } catch (Exception) { } } } /// <summary> /// 递归接收消息方法 /// </summary> internal void ReceiveAsync() { try { if (!this.IsDispose && this._Socket.Connected) { , this.BufferSize, SocketFlags.None, out SenderError, this.aCallback, this); CheckSocketError(ReceiveError); } } catch (System.Net.Sockets.SocketException) { this.Close("链接已经被关闭"); } catch (System.ObjectDisposedException) { this.Close("链接已经被关闭"); } } /// <summary> /// 接收消息回调函数 /// </summary> /// <param name="iar"></param> private void ReceiveCallback(IAsyncResult iar) { if (!this.IsDispose) { try { //接受消息 ReceiveSize = _Socket.EndReceive(iar, out ReceiveError); //检查状态码 if (!CheckSocketError(ReceiveError) && SocketError.Success == ReceiveError) { //判断接受的字节数 ) { byte[] rbuff = new byte[ReceiveSize]; Array.Copy(this.Buffers, rbuff, ReceiveSize); this.Receive(rbuff); //重置连续收到空字节数 ZeroCount = ; //继续开始异步接受消息 ReceiveAsync(); } else { ZeroCount++; ) { this.Close("错误链接"); } } } } catch (System.Net.Sockets.SocketException) { this.Close("链接已经被关闭"); } catch (System.ObjectDisposedException) { this.Close("链接已经被关闭"); } } } /// <summary> /// 错误判断 /// </summary> /// <param name="socketError"></param> /// <returns></returns> bool CheckSocketError(SocketError socketError) { switch ((socketError)) { case SocketError.SocketError: case SocketError.VersionNotSupported: case SocketError.TryAgain: case SocketError.ProtocolFamilyNotSupported: case SocketError.ConnectionAborted: case SocketError.ConnectionRefused: case SocketError.ConnectionReset: case SocketError.Disconnecting: case SocketError.HostDown: case SocketError.HostNotFound: case SocketError.HostUnreachable: case SocketError.NetworkDown: case SocketError.NetworkReset: case SocketError.NetworkUnreachable: case SocketError.NoData: case SocketError.OperationAborted: case SocketError.Shutdown: case SocketError.SystemNotReady: case SocketError.TooManyOpenSockets: this.Close(socketError.ToString()); return true; } return false; } /// <summary> /// 发送消息方法 /// </summary> internal int SendMsg(byte[] buffer) { ; try { if (!this.IsDispose) { size = , buffer.Length, SocketFlags.None, out SenderError); CheckSocketError(SenderError); } } catch (System.ObjectDisposedException) { this.Close("链接已经被关闭"); } catch (System.Net.Sockets.SocketException) { this.Close("链接已经被关闭"); } buffer = null; return size; } }
上面我们事先了socket的异步接受消息,和同步发送消息已经关闭释放资源代码
接受消息net底层提供的接受消息的方法有很多,为什么我们要选择上面所写的呢?那是为了兼容U3D,silverlight, wpf, wp, wf,等程序可执行,不在重复做相同工作。
现在我们来创建一个实现类 TSocketClient
public class TSocketClient : TSocketBase { /// <summary> /// 是否是服务器端的资源 /// </summary> bool isServer = false; /// <summary> /// 客户端主动请求服务器 /// </summary> /// <param name="ip"></param> /// <param name="port"></param> ) { isServer = false; this._Socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); this._Socket.Connect(ip, port); this.SetSocket(); this.ReceiveAsync(); } /// <summary> /// 这个是服务器收到有效链接初始化 /// </summary> /// <param name="socket"></param> public TSocketClient(Socket socket) { isServer = true; this._Socket = socket; this.SetSocket(); this.ReceiveAsync(); } /// <summary> /// 收到消息后 /// </summary> /// <param name="rbuff"></param> public override void Receive(byte[] rbuff) { Console.WriteLine("Receive Msg:" + System.Text.UTF8Encoding.Default.GetString(rbuff)); if (isServer) { this.SendMsg(System.Text.UTF8Encoding.Default.GetBytes("Holle Client!")); } } }
因为是测试示例,所以我把服务器和客户端实现类写成了,只是用来不同的构造函数来区分,是客户端还是服务器的标识
接下来我们测试一下代码
class Program { static void Main(string[] args) { TCPListener tcp = new TCPListener(); TSocketClient client = new TSocketClient(); client.SendMsg(System.Text.UTF8Encoding.Default.GetBytes("Holle Server!")); Console.ReadLine(); } }
运行结果看出,我们连接成功并且发送消息成功。
C# Socket系列二 简单的创建 socket 通信的更多相关文章
- C# Socket系列一 简单的创建socket的监听
socket的应用场景,在快速,稳定,保持长连接的数据传输代码.Http也是socket封装出来的,基于一次请求一次回复,然后断开的socket连接封装. 比如我们常见的游戏服务器,目前的很火的物联网 ...
- LINQ to Sql系列二 简单查询和联接查询
这一篇文章主要总结LINQ to sql的简单查询(单表查询)和联接查询(多表查询) 单表查询 需求是我们要输出TClass表中的结果.使用了from-in-select语句,代码如下: public ...
- 简单的同步Socket程序服务端
首先,Socket是.Net提供的 System.Net.Sockets命名空间的Scoket类为网络通信提供了一套丰富的方法和属性 服务器按照Socket的基本流程 先创建Socket 在用Bind ...
- python 实现一个简单tcp epoll socket
python 实现一个epoll server #!/usr/bin/env python #-*- coding:utf-8 -*- import socket import select impo ...
- import socket模块二
---恢复内容开始--- 优化两个小脚本实现不间断聊天: server.py: import socket sk = socket.socket() # 创建socket addess = ('127 ...
- Socket学习总结系列(二) -- CocoaAsyncSocket
这是系列的第二篇 这是这个系列文章的第二篇,要是没有看第一篇的还是建议看看第一篇,以为这个是接着第一篇梳理的 先大概的总结一下在上篇的文章中说的些内容: 1. 整理了一下做IM我们有那些途径,以及我们 ...
- C# Socket系列三 socket通信的封包和拆包
通过系列二 我们已经实现了socket的简单通信 接下来我们测试一下,在时间应用的场景下,我们会快速且大量的传输数据的情况! class Program { static void Main(stri ...
- socket编程——一个简单的样例
从一个简单的使用TCP样例開始socket编程,其基本过程例如以下: server client ++ ...
- socket计划——一个简单的例子
从一个简单易用TCP样品开始socket计划,的基本过程例如下列: server client +++ ...
随机推荐
- [ASE][Daily Scrum]12.15
这两周事情好多~ 组里面的事情,出国的申请出国………… 不过整体来说我们sprint3并没有安排太多的工作,所以完成情况尚可. 大地图和AI花费了不少时间,
- System.Data.SqlClient.SqlError: FILESTREAM 功能被禁用”的错误
还原sql2008数据库时遇到"System.Data.SqlClient.SqlError: FILESTREAM 功能被禁用"的错误,在网上搜索解决方案如下: 1.在" ...
- 【Win10】UAP/UWP/通用 开发之 x:DeferLoadStrategy
[Some information relates to pre-released product which may be substantially modified before it's co ...
- node(thrift)
thrift是一种跨语言的RPC框架,据说uber采在node.js项目中采用thrfit后,比原有的http+json的方式提高近20倍的性能. 所谓的RPC本质上就是客户端将需要调用的方法名和参数 ...
- 译文---C#堆VS栈(Part Four)
前言 在本系列的第一篇文章<C#堆栈对比(Part Three)>中,介绍了值类型和引用类型在Copy上的区别以及如何实现引用类型的克隆以及使用ICloneable接口等内容. 本文为文章 ...
- [ZigBee] 10、ZigBee之睡眠定时器
0.概述 睡眠定时器用于设置系统进入和退出低功耗睡眠模式之间的周期.睡眠定时器还用于当进入低功耗睡眠模式时,维持定时器2 的定时. 睡眠定时器的主要功能如下: ● 24 位的定时器正计数器,运行在32 ...
- Chrome扩展程序的二次开发:把它改得更适合自己使用
我当然知道未经作者允许修改别人程序是不道德的了,但作为学习研究之用还是无可厚非,这里仅供交流. 一切都是需求驱动的 话说某天我在网上猎奇的时候无意间发现这么一款神奇的谷歌浏览器插件:Extension ...
- [源码]NumberToUpper 数字转中文
使用时需开启unsafe选项 构造函数有4个参数 number : 数字文本 isSimplified : 是否只使用简体中文,默认:false isMoney : 是否是金额模式(忽略小数点后3位, ...
- git rm–r folder fatal:pathspec "" did not match any files
问题描述: 某年某月某日,在查看git库的时候,发现文件的分布和文件夹的名字是极其不合理的,所以移动和重命名了某些文件. 在删除(git rm –r folder)一个空文件夹的时候,出现错误:fat ...
- Atitit Server Side Include ssi服务端包含规范 csi esi
Atitit Server Side Include ssi服务端包含规范 csi esi 一.CSI (Client Side Includes) 1 1.1. 客户端包含1 1.2. Ang ...