当前位置: 首页 > 编程日记 > 正文

C# Socket编程(5)使用TCP Socket

TCP 协议(Transmission Control Protocol,传输控制协议)是TCP/IP体系中面向连接(connection oriented)的传输层(transport layer)TCP协议能够检测和恢复IP层提供的主机到主机的信道中可能发生的报文丢失、重复以及其他错误。由于TCP协议是一种面向连接协议:在使用它进行通信之前,两个应用程序之间首先要建立一个TCP连接。TCP能够在网络中提供双工和可靠的的服务。

 阅读目录:

  1.TCP概述

2.在.NET平台TCP应用的工作模式

2.1 了解TcpListener和TcpClient

3.解决TCP的消息无边界问题

3.1 发送固定长度的消息

3.2 将消息长度与消息一起发送

3.3 使用特殊标记分隔消息

 4.一个同步TCP Socket示例

  5.示例源码下载

  6.进一步阅读&参考资料

1.TCP概述

通信双方建立了TCP连接后,双方就可以相互发送数据了。TCP负责把用户数据(字节流)按照一定格式和长度组成多个数据报进行发送,然后在接到数据报之后分解按顺序重新组装和恢复用户数据。利用TCP传输数据时,数据时以字节的形式进行传输的。客户端和服务端建立连接后,发送数据方需要先将数据转换为字节流,然后将字节流发送到对方。TCP协议主要有以下特点:

  1. 是面向连接的传输层协议
  2. 每个TCP连接只能有两个端点,且只能一对一通信
  3. 通过TCP连接传送数据能够保证报文的完整和准确性
  4. 数据只能够以字节流的形式传输
  5. 传输的数据无消息边界

2.在.NET平台TCP应用的工作模式

在.NET平台下开发TCP应用程序,框架提供两种工作方式,①同步工作方式 ②异步工作方式。这里所说的同步工作方式和异步工作方式和线程间的同步并不是一个概念。线程间的同步指的是不同线程或其他共享资源具有先后关联的关系;而同步TCP和异步TCP指的是TCP编程中采用的两种不同的工作方式,即:从执行到方式、接收或监听语句时,程序是否继续往下执行,继续执行的就是异步TCP,如果程序阻塞那就是同步TCP

与同步工作方式和异步工作方式相对应,利用Socket类开发应用.NET框架也提供了相应的编程方式:分别是同步Socket编程异步Socket编程。为了简化编程的复杂度,.NET将Socket类进行进一步的封装,提供了两个类:TcpClient类和TcpListener类,这两个类也分别提供同步和异步工作方式的API。

2.1 了解TcpListener和TcpClient

通过前面我们知道:TcpClient类和TcpListener类简化了Socket编程的复杂度,但是要注意:TcpClientTcpListener这两个类只支持标准协议编程,如果需要编写非标准协议的应用程序,只能使用Socket来实现。

TcpClient类用于提供本机主机和远程主机的连接信息,而TcpListener类则用于监听客户端的请求(这两个类的更多信息可以参考MSDN类库,文中已经给出连接,这里就不在赘述了)。当Socket通信双发建立了连接后,创建了TcpClient对象,就可以使用该对象的GetStream()方法得到NetworkStream对象,然后再利用网络流对象向远程主机发送或接收流数据。

3.解决TCP的无消息边界问题

我们知道网络数据传输是基于流的,在采用TCP通信保证了我们接收和发送数据顺序和完整性,但是在实际的网络传输过程可能会出现发送方和接收方消息不一致的情况。例如:第一次发送的数据为“123456”,第二次发送的数据为“ABCDEF”,有时候可能会出现这种情况:“123456ABCDEF”同时接收了;或者是先接收“123456ABC”,然后在接收“DEF”等情况。之所以出现这种情况是因为:TCP是一种以字节流形式传输的、无消息边界的协议,由于网络中不确定因数的影响,因此不能够保证每个Send方法发送的数据被对应的Recive读取。所以在实际的Socket应用程序开发是必须要考虑消息边界的问题否则就有可能出现数据错误等问题。解决TCP消息边界一般使用下面的三种方式,我们可以根据场景的不同选用不同的方式。

3.1 发送固定长度的消息

这种方式适用于消息长度固定的场景。具体实现时可以使用BinaryReader/BinaryWriter对象每次向网络流,发送/读取一个固定长度的数据即可。例如每次发送一个int类型的32位整数。

1             TcpClient client = new TcpClient("www.baidu.com", 5968);
2             NetworkStream m_NetStream = client.GetStream();
3             BinaryWriter bw = new BinaryWriter(m_NetStream, Encoding.UTF8);
4             bw.Write(99);

3.2 将消息长度与消息一起发送

这种方式一般在每次发送消息的前面用4个字节表面本次消息的长度,然后将包含消息长度的消息发送给对方;对方收到消息后,首先从消息的前四个字节读取消息长度,然后根据消息长度值接收发送方发送的数据。这种方法适用于任何场合,在这里我们可以利用BinaryReaderBinaryWriter对象来对NetworkStream进行进一步的封装,当我们使用BinaryWriter对象调用Write(+18重载)方法向网络流写入数据时,该方法会自动计算发出送数据占用的字节数,并使用4(根据发送数据类型)个字节附加到字符串前面;然后另一方使用BinaryReader对象的对应于BinaryWriter对象的Write()方法读取数据时,它会首先读取数据的长度,并自动根据数据前缀读取指定长度的数据。

3.3 使用特殊标记分隔消息

这种方式适用于消息中不包含特殊标记的场合。例如:在每个命令后面添加回车换行(\r\n)符号作为分隔符的场合。如果对于字符串处理,实现这种方法最简便的途径是使用StreamWriter对象和StreamReader对象。发送时使用StreamWriter对象的WriteLine()方法将发送的字符串写入网络流,接收方只需需要调用StreamReader对象的ReadLine()方法将以回车换行符作为分隔符的字符串从网络流中读取即可。

4.同步TCP Socket 示例程序

经过前面知识的积淀,现在我们直接通过创建一个简单的聊天程序来基于同步TCP Socket网络聊天程序,程序的实现比较简单,服务器接收多个客户端连接,客户端和客户端直接通过服务器中转消息达到相互通信的目的。客户端和服务器直接的消息交互使用JSON来进行传递,在这里使用了第三方的JSON库JSON.NET(关于JSON.NET的使用细节参考:JSON.NET使用小结)。下面是程序运行的效果:

运行服务端:

打开多个客户端,在在线列表中选择聊天对象,发送聊天信息:

 

示例源码:猛击下载

参考资料&进一步阅读

维基百科:传输控制协议(TCP)

《C#网络应用编程2》

作者:晴天猪

出处:http://www.cnblogs.com/IPrograming

本文版权归作者和博客园共有,欢迎转载,并请注明出处。

相关文章:

opencv 检测直线、线段、圆、矩形

转自:http://blog.csdn.net/byxdaz/archive/2009/12/01/4912136.aspx 检测直线:cvHoughLines,cvHoughLines2 检测圆:cvHoughCircles 检测矩形:opencv中没有对应的函数,下面有段代码可以检测矩形&#xff…

kaldi 源码分析(十) - gmm-init-mono.c分析

一直没有搞明白 hmm-gmm 之间是通过什么联系起来的,花了些时间查代码,看到最直观联系的就是 gmm-init-mono 工具。 gmm-init-mono 基础类通过上述看到,主要的配置都是 在 topo 文件中, 这里需要将一些常见的名称理解下来,这里直接…

你最需要了解的H3C交换机端口安全模式

以下内容摘自正在全国热销的《Cisco/H3C交换机高级配置与管理技术手册》一书(畅销经典——《Cisco/H3C交换机配置与管理完全手册》(第二版)的配套姊妹篇)。目前京东网和卓越网上都有“满150元减50元,满300元减100元”的…

TCL发布7项AI合作项目,聘任蒋涛为技术顾问

作者 | 夕颜出品 | AI科技大本营(ID:rgznai100)2019 年 6 月 14 日,TCL 举办了以“技术无疆界,合作赢未来”为主题的技术合作开放大会。会上,TCL 面向全球发布了 13 项技术合作项目,其中包括 7 项人工智能技…

Microsoft Platform SDK Febrary 2003更新vc6的SDK网址

Microsoft Platform SDK Febrary 2003更新vc6的SDK网址,目前找到3处,分别为: 1、http://www.x86pro.com/plus/view.php?aid100 2、http://blog.csdn.net/Mobidogs/archive/2007/02/22/1512620.aspx 3、http://blog.chinaunix.net/u1/34831…

11岁姑娘挑战8分钟编程小程序!蚂蚁金服董事长井贤栋:欢迎加入

小蚂蚁说: 9月19日,在阿里巴巴云栖大会现场,一位年仅11岁的小学生万海妍报名参加了支付宝8分钟小程序挑战赛,成为现场最年轻选手。据悉,蚂蚁金服董事长兼CEO井贤栋在会后对万海妍十分赞赏,向她发出邀请&…

MST配置详解

一、 组网需求1. 网络中所有设备都属于同一个MST域。SW1和SW2为汇聚层设备,SW3和SW4为接入层设备。 2. 通过配置MSTP,使不同VLAN的报文按照不同的MSTI转发: VLAN10的报文沿MSTI1转发,VLAN30沿MSTI3转发&#…

CImg库的一个简单例子

转自:http://www.cppprog.com/2009/0424/106.html CImg是一个跨平台的C的图像处理库,提供了加载、处理、显示、保存等一系列功能,其中的图像处理功能尤其强大。 首先,建议先到这里欣赏一下使用CImg代码做的Demo,就是它…

继AutoML后,第四范式发布软硬一体化AI集成系统SageOne

作者 | 夕颜出品 | AI科技大本营(ID:rgznai100)6 月 20 日,AI产品和服务提供商第四范式宣布发布最新 AI 系列产品SageOne Appliance软硬一体化AI集成系统,性能较市面开源工具或GPU解决方案至少提高6倍。这是继 2018 年9 月 18 日第…

Apache 基金会宣布 Apache Pulsar 毕业成为顶级项目

开发四年只会写业务代码,分布式高并发都不会还做程序员? Apache 软件基金会宣布,Apache Pulsar 已经成功地从孵化毕业,成为基金会的一个新的顶级项目。Pulsar 是一个分布式的消息发布/订阅传递平台,旨在实现可扩展性…

CI报Disallowed Key Characters的解决

用CI框架时,有时候会遇到这么一个问题,打开网页,只显示 Disallowed Key Characters 错误提示。有人说 url 里有非法字符。但是确定 url 是纯英文的,问题还是出来了。但清空浏览器历史记录和cookies后。 刷新就没问题了。有时候。打…

刷新中文阅读理解水平,哈工大讯飞联合发布基于全词覆盖中文BERT预训练模型...

作者 | HFL来源 | 哈工大讯飞联合实验室(ID:rgznai100)为了进一步促进中文自然语言处理的研究发展,哈工大讯飞联合实验室发布基于全词覆盖(Whole Word Masking)的中文BERT预训练模型。我们在多个中文数据集上得到了较好…

CImg库中部分函数的作用和用法

部分内容来自于CImg参考手册或CImg的Doxygen手册 1、宏cimg_usage(usage):可以被用来描述程序的目的和使用情况。它通常被插入到 int main(int argc, char **argv)的定义之后。 参数:usage:描述程序目的和使用情况的字符串。 前置条件:使用ci…

golang通过itemid获取zabbix graph监控图

2019独角兽企业重金招聘Python工程师标准>>> #简述 本文将使用golang和第三方http client 库gorequest编写。如需要只使用golang 标准库可以参考我的另外一篇文章golang通过itemid获取zabbix graph监控图 #F&Q 为什么是golang? 网上很容易就能找到使…

n后问题-回溯法

问题描述: 在n*n的棋盘上放置彼此不受攻击的n个皇后。按国际象棋的规则,皇后可以与之处在同一行或者同一列或同一斜线上的棋子。 n后问题等价于在n*n格的棋盘上放置n皇后,任何2个皇后不放在同一行或同一列的斜线上。 算法设计: |i…

CImg库介绍

转自:http://www.cppprog.com/2009/0424/106.html CImg是一个跨平台的C的图像处理库,提供了加载、处理、显示、保存等一系列功能,其中的图像处理功能尤其强大。 首先,建议先到这里欣赏一下使用CImg代码做的Demo,就是它…

谷歌、阿里们的杀手锏:三大领域,十大深度学习CTR模型演化图谱

作者 | 王喆来源 | 转载自知乎专栏王喆的机器学习笔记今天我们一起回顾一下近3年来的所有主流深度学习CTR模型,也是我工作之余的知识总结,希望能帮大家梳理推荐系统、计算广告领域在深度学习方面的前沿进展。随着微软的Deep Crossing,Google的…

MariaDB 基金会 CEO 宣布将于 10 月 1 日卸任

开发四年只会写业务代码,分布式高并发都不会还做程序员? 近日,MariaDB 基金会 CEO Otto Keklinen 在官网宣布自己将在今年 10 月 1 日正式卸任 CEO,转而退居后线,以 CEO 特别顾问的身份辅助新 CEO 顺利渡过过渡期。从…

思科生成树命令之debug spanning-tree(本文转载自:www.91ccie.coml

debug spanning-tree 命令:debug spanning-treeno debug spanning-tree功能:打开MSTP 的调试信息;本命令的no 操作为关闭MSTP 调试信息。参数:无命令模式:特权模式使用指南:该命令是MSTP 庞大复杂debug 功能…

CImg库中CImg,CImgList,CImgDisplay三个类的介绍

转自:http://www.cppprog.com/2009/0426/108.html 本文简单介绍了CImg库中的三个大类:CImg,CImgList,CImgDisplay。然后给出了让CImg在HDC上绘图以及与HBITMAP互换的方法,为部署CImg到Windows GUI程序中提供了基本支持。 上回介绍了CImg模板…

这可能是Python面向对象编程的最佳实践

作者 | 崔庆才来源 | 进击的Coder(ID:FightingCoder)Python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了或者某一对象非常复杂了,其中的一些…

mysql之 CentOS系统针对mysql参数优化

内核相关参数(/etc/sysctl.conf) 以下参数可以直接放到sysctl.conf文件的末尾: net.core.somaxconn 65535 net.core.netdev_max_backlog 65535 net.ipv4.tcp_max_syn_backlog 65535 加快TCP连接的回收: net.i…

天猫双十一神话恐终结

2011年双十一大促,天猫商城创造了单日33.6亿的促销奇迹,是2010年同日交易额的近4倍。今年双十一即将来临,淘宝还能再创奇迹吗?何玺认为,淘宝双十一的神话恐终结,理由如下。 一、电商促销年消费被透支 年初 …

opencv图像旋转

转自&#xff1a;http://download.csdn.net/source/2642701 /* 程序名&#xff1a;rotate.c 功能&#xff1a;读入图像文件&#xff0c;做图像旋转转&#xff0c;然后显示图像在屏幕上 */ #include <stdlib.h> #include <stdio.h> #include <math.h> #inclu…

机器如何读懂人心:Keras实现Self-Attention文本分类

作者 | 小宋是呢转载自CSDN博客一、Self-Attention概念详解了解了模型大致原理&#xff0c;我们可以详细的看一下究竟Self-Attention结构是怎样的。其基本结构如下对于self-attention来讲&#xff0c;Q(Query), K(Key), V(Value)三个矩阵均来自同一输入&#xff0c;首先我们要计…

通俗易懂!使用Excel和TF实现Transformer

作者 | 石晓文转载自小小挖掘机&#xff08;ID:wAIsjwj&#xff09;本文旨在通过最通俗易懂的过程来详解Transformer的每个步骤&#xff01;假设我们在做一个从中文翻译到英文的过程&#xff0c;我们的词表很简单如下&#xff1a;中文词表&#xff1a;[机、器、学、习] 英文词表…

通过注册表修改VC6.0的字体【转】

2019独角兽企业重金招聘Python工程师标准>>> 在VC6.0下更改字体&#xff0c;我们一般通过菜单-Tools-Options-Format来更改 但在我的win7 64位系统下这一选项下的字体和字体颜色是空的&#xff0c;无法选择 所以我想起来通过注册表来更改。 WinR输入“Regedit”&…

Java中创建String的两种方式差异

我们知道创建一个String类型的变量一般有以下两种方法&#xff1a; String str1 "abcd"; String str2 new String("abcd"); 那么为什么会存在这两种创建方式呢&#xff0c;它们在内存中的表现形式各有什么区别&#xff1f; 方法1&#xff1a; String a …

OpenCV支持的图像格式

OpenCV目前支持的图像格式包括&#xff1a; Windows位图文件 - BMP, DIB&#xff1b; JPEG文件 - JPEG, JPG, JPE&#xff1b; 便携式网络图片 - PNG&#xff1b; 便携式图像格式 - PBM&#xff0c;PGM&#xff0c;PPM&#xff1b; Sun rasters - SR&#xff0c;RAS&#xff…

Debian Linux下的Python学习——控制流

python中有三种控制流语句:if、for和while。 1. if语句用法( if..elif..else) 代码: 运行: 注意:raw_input函数要求输入一个字符串,int把这个字符串转换为整数 2.for语句用法 (for ... else) 代码: 运行: 注:else部分是可选的。如果包含else&#xff0c;它总是在for循环结束后…