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 +++ ...
随机推荐
- .Net mvc 后台传单引号错误'
今天调试半天程序 结果出现JS 无法eval() 网上找个半天解决办法无果 最后 是因为后台输出单引号’ 到前台为' 解决办法 给一个隐藏文本框或者标签赋值 再取出来就能显示单引号了
- windows设置笔记
1. 使用Sudo提升权限 http://www.alexblair.org/user-alexblair-post-1046.html 新建 sudo.js 放到 C:\windows\下面,内容如 ...
- Win10 UWP应用发布流程
简介 Win10 UWP应用作为和Win8.1 UAP应用不同的一种新应用形式,其上传至Windows应用商店的流程也有了一些改变. 这篇博文记录了我们发布一款Win10 UWP应用的基本流程,希望为 ...
- 在.net中使用aquiles访问Cassandra(一)
aquiles是.net下基于Thrift协议访问Cassandra的第三方类库,官方地址是: http://aquiles.codeplex.com/ 1.下载类库文件: http://aqui ...
- ASP.NET MVC实现仪表程序
1.1.1 摘要 在大多数情况下,我们的Web程序不仅仅需要给用户提供具体数据,在一些情况下,我们还需要给高级的用户或管理者提供数据汇总和分析图表之类的功能. 如果我们不想显示一大堆烦心的数据,希望通 ...
- 微软Edge 内嵌的JavaScript 引擎即将开源
微软于今日(2015年12月10日)宣布即将开源Chakra核心控件,并改名为“ChakraCore”,该控件包含所有Edge JavaScript 引擎的所有核心功能.ChakraCore 将于下月 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十六):AccessToken自动管理机制
在<Senparc.Weixin.MP SDK 微信公众平台开发教程(八):通用接口说明>中,我介绍了获取AccessToken(通用接口)的方法. 在实际的开发过程中,所有的高级接口都需 ...
- Java基础之I/O和file
五.IO流1.IO流概述 (1)用来处理设备(硬盘,控制台,内存)间的数据. (2)java中对数据的操作都是通过流的方式. (3)java用于操作流的类都在io包中. (4)按照流操作的数据的类型不 ...
- Java用来进行批量文件重命名,批量提取特定类型文件
原因: 因为在网上下载视频教程,有的名字特别长,一般都是机构或者网站的宣传,不方便直接看到视频的简介,所以做了下面的第一个功能. 因为老师发的课件中,文件夹太多,想把docx都放在同一个文件夹下面,一 ...
- Node.js与Sails~自定义响应体responses
回到目录 在Node.js里,你可以控制请求和响应,自己可以定义自己的响应方式,如对文本如何响应,对json如何响应,对图像流如何响应等等,而这些在Sails架构里,变得更加容易和清晰了,它位于项目的 ...