TCP简介

  TCP是Transmission Control Protocol(传输控制协议)的简称,是TCP/IP体系中面向连接的运输层协议,在网络中提供全双工的和可靠的服务。

  TCP最主要的特点:

  (1)是面向连接的传输层协议;

  (2)每个TCP连接只能有两个端点,而且只能一对一通信,不能一点对多点直接通信。

  (3)通过TCP连接传送的数据,能保证数据无差错、不丢失、不重复地准确到达接收方,并且保证各数据到达的顺序与数据发出的顺序相同。

  (4)数据以字节流的方式传输。

  (5)传输的数据无消息边界。

  利用TCP开发应用程序时,.NET框架提供两种工作方式.

  (1)同步工作方式 指利用TCP编写的程序执行到发送、接收或监听语句时,在未完成工作前不再继续往下执行,

    即处于阻塞状态,直到该语句完成相应的工作后才继续执行下一条语句;

  (2)异步工作方式 异步工作方式是指程序执行到发送、接收或监听语句时,不论工作是否完成,都会继续往下执行。

    例如:同步接收数据时,接收方执行到接收语句后将处于阻塞方式,只有接收到对方发来的数据后才继续执行下一条语句;

    而如果采用异步工作方式,则接收方在执行到接收语句后,无论是否接收到对方发来的数据,程序都继续往下执行。

TcpListener类与TcpClient类

  TcpListener类与TcpClient类两个类均封装了底层的套接字,并分别提供了对套接字进一步封装后的同步和异步操作的方法,降低了TCP应用编程的难度。

  TcpListener类用于侦听和接受传入的连接请求。

  TcpClient类用于提供本地主机和远程主机的连接信息。

  注意,TcpListener和TcpClient只支持标准协议编程。如果希望编写非标准协议的程序,只能使用套接字来实现。

  编写服务器端程序的一般步骤为:

  使用对套接字封装后的类,编写基于TCP的服务器端程序的 一般步骤为:

  (1)创建一个TcpListener对象,然后调用该对象的Start方法在指定的端口进行监听。

  (2)在单独的线程中,循环调用AcceptTcpClient方法接受客户端的连接请求,并根据该方法的返回的结果得到与该客户端对应的TcpClient对象。

  (3)每得到一个新的TcpClient对象,就创建一个与该客户对应的线程,在线程中与对应的客户进行通信。

  (4)根据传送信息的情况确定是否关闭与客户的连接。

  编写客户端程序的一般步骤为:

  使用对套接字封装后的类,编写基于TCP的客户端程序的一 般步骤如下:

  (1)利用TcpClient的构造函数创建一个TcpClient对象。

  (2)使用Connect方法与服务器建立连接。

  (3)利用TcpClient对象的GetStream方法得到网络流,然后利用该网络流与服务器进行数据传输。

  (4)创建一个线程监听指定的端口,循环接收并处理服务器发送过来的信息。

  (5)完成工作后,向服务器发送关闭信息,并关闭与服务器的连接。

  在网络传输中,可能会出现发送方一次发送的消息与接收方一次接收的消息不一致的现象。

  这主要是因为TCP协议是字节流形式的、无消息边界的协议,由于受网络传输中的不确定因素的影响,因此不能保证单个Send方法发送的数据被单个Receive方法读取。

  实际应用中,解决TCP协议消息边界问题的方法有三种

  1、发送固定长度的消息,该方法适用于消息长度固定的场合。

  2、将消息长度与消息一起发送,这种方法适用于任何场合。

  3、使用特殊标记分隔消息,这种方法主要用于消息中不包含特殊标记的场合。

  第一种通过网络流来解决消息边界问题:

 //客户端
        private BinaryReader br;
        private BinaryWriter bw;
        //客户端获取网络流
        NetworkStream networkStream = client.GetStream();

        /// <summary>向服务器端发送信息</summary>
        private void SendMessage(string message)
        {
            try
            {
                //将字符串写入网络流,此方法会自动附加字符串长度前缀
                bw.Write(message);
                bw.Flush();
            }
            catch
            {
                throw new Exception("发送失败!");
            }
        }

        //服务器端
        //读取网络流
        string receiveString = br.ReadString();

  第二种定义消息开始和结尾,字节流的形式传输

/// <summary>
        /// 受保护将要传送数据转成二进制数组方法
        /// </summary>
        /// <param name="obj">要转换的对象</param>
        /// <returns>被转换成二进制数</returns>
        internal virtual byte[] FromObjectToBytes(object obj)
        {
            lock (this)
            {
                ;
                byte[] bytesContent = null;
                byte[] bytesResult = null;
                byte[] bytesLength = null;

                if (obj is string)
                {
                    byteType = (byte)EnumDataMark.Text;
                    bytesContent = Encoding.UTF8.GetBytes(obj.ToString());
                    bytesLength = BitConverter.GetBytes(bytesContent.Length);
                }
                else if (obj is object)
                {
                    byteType = (byte)EnumDataMark.Obj;

                    try
                    {
                        MemoryStream ms = new MemoryStream();
                        BinaryFormatter bf = new BinaryFormatter();
                        bf.Serialize(ms, obj);
                        ms.Seek(, SeekOrigin.Begin);

                        bytesLength = BitConverter.GetBytes((int)ms.Length);
                        bytesContent = new byte[ms.Length];
                        ms.Read(bytesContent, , (int)ms.Length);
                        ms.Close();
                    }
                    catch (SerializationException se)
                    {
                        throw se;
                    }
                }

                bytesResult = ];
                bytesResult[] = (byte)EnumDataMark.Start;//开始
                bytesResult[] = byteType;
                Array.Copy(bytesLength, , bytesResult, , bytesLength.Length);
                Array.Copy(bytesContent, , bytesResult, , bytesContent.Length);
                bytesResult[bytesResult.Length - ] = (byte)EnumDataMark.end;//结尾

                return bytesResult;
            }
        }

九、Socket之TCP编程的更多相关文章

  1. 【Socket编程】通过Socket实现TCP编程

    通过Socket实现TCP编程 Socket通信 : 1.TCP协议是面向对象连接.可靠的.有序的,以字节流的方式发送数据. 2.基于TCP协议实现网络通信的类: 客户端----Socket类 服务器 ...

  2. JAVA 通过 Socket 实现 TCP 编程

    简介 TCP简介 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机 ...

  3. 牛客网Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤

    福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑         Java全栈大联盟   ...

  4. 通过Socket实现TCP编程,用户登录之服务器相应客户端,客户端和服务端之间的通信

    服务器端: 1.创建ServerSocket对象,绑定监听端口: 2.通过accept()方法监听客户端请求: 3.建立连接后通过输入流读取客户端发送的请求信息; 4.通过输出流向客户端发送响应信息; ...

  5. python网络-Socket之TCP编程(26)

    一.TCP简介 1.TCP介绍 TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TC ...

  6. 【Linux/unix网络编程】之使用socket进行TCP编程

    实验一 TCP数据发送与接收 [实验目的] 1.熟练掌握套接字函数的使用方法. 2.应用套接字函数完成基本TCP通讯,实现服务器与客户端的信息交互. [实验学时] 4学时 [实验内容] 实现一个服务器 ...

  7. 通过Socket实现TCP编程(十二)

    原文链接:https://www.cnblogs.com/hysum/p/7531529.html Socket通信 : TCP协议是面向对象连接.可靠的.有序的,以字节流的方式发送数据. 基于TCP ...

  8. Java的Socket通信----通过 Socket 实现 TCP 编程之多线程demo(2)

    JAVA Socket简介 所谓socket 通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过”套接字”向网络发出请求或者应答网络请求. import java.io ...

  9. 网络层、传输层、应用层、端口通信协议编程接口 - http,socket,tcp/ip 网络传输与通讯知识总结

    引: http://coach.iteye.com/blog/2024511 什么是TCP和UDP,以及二者区别是什么? TCP的全称为传输控制协议.这种协议可以提供面向连接的.可靠的.点到点的通信. ...

随机推荐

  1. 【BZOJ 3993】【SDOI 2015】星际战争

    http://www.lydsy.com/JudgeOnline/problem.php?id=3993 调了好长时间啊 这道题设时间为time,那么对于m个武器从S向这m个点连容量为time*Bi的 ...

  2. Codevs 3305 水果姐逛水果街Ⅱ 倍增LCA

    题目:http://codevs.cn/problem/3305/  时间限制: 2 s   空间限制: 256000 KB   题目等级 : 钻石 Diamond 题解       题目描述 Des ...

  3. WiEngine+Eclipse+CDT+Sequoyah实现c++编程智能感知提示

    经过一段时间的摸索,我初步肯定自己基于WiEngine平台和C++开发跨Android/iPhone游戏的最佳(至少目前)环境为: Eclipse+CDT+Sequoyah 第一,JAVA代码调试技术 ...

  4. 移动HTML5前端性能优化总结

    概述 1. PC优化手段在Mobile侧同样适用 2. 在Mobile侧我们提出三秒种渲染完成首屏指标 3. 基于第二点,首屏加载3秒完成或使用Loading 4. 基于联通3G网络平均338KB/s ...

  5. WSL优化 (Windows Subsystem for Linux) Linux子系统优化配置

    目录 wsl优化 (Windows Subsystem for Linux) Linux子系统优化 1. 永久修改wsl终端字体 2. 修改Linux终端配色 3. 添加WSL到右键菜单 wsl优化 ...

  6. 在GridControl控件上绑定图片的几种操作方式

    我们知道,基于DevExpress的开发Winform的项目界面的时候,GridControl控件是经常用来绑定数据的,一般以常规的字符内容为主,有时候也会有图片的显示需要,那么如果显示图片,我们应该 ...

  7. Windows系统下在Git Bash中把文件内容复制到剪贴板的命令

    众所周知,在OS系统中,复制文件内容到剪贴板(比如复制公钥到剪贴板)的命令是: pbcopy < ~/.ssh/id_rsa.pub 在Win7或者Win10下这条命令就没用了.可以这样: cl ...

  8. Objective-C学习笔记(三)——用Objective-C编写第一个程序:Hello,World!

    不管是哪一个程序猿,或者是学习哪一门计算机语言.写的第一个程序基本上就是Hello World. 今天我们用OC来实现第一个程序:Hello World. 在Xcode中选择新建一个项目,在对话框中选 ...

  9. gcc常用命令使用

    gcc编译文件过程 .c文件到 .i文件 到.s(汇编文件) 到.o文件,再到可执行文件 .c到.i 实操一下: test.c文件如下 : #include <stdlib.h> #inc ...

  10. python记录_day06

    一.小数据池 注意大前提!!!! 小数据池只针对整数.字符串和bool值,因为这些数据是不可变的,这样数据的共享才安全 小数据池也称为小整数缓存机制或驻留机制,是指在不同代码块创建部分小数据对象(具体 ...