精华内容
下载资源
问答
  • TCP/IP 应用程序的通信连接模式

    千次阅读 2014-02-17 13:10:25
    TCP/IP 应用层与应用程序 TCP/IP 起源于二十世纪 60 年代末美国政府资助的一个分组交换网络研究项目,它是一个真正的开放协议,很多不同厂家生产各种型号的计算机,它们运行完全不同的操作系统,但 TCP/IP 协议组件...

    TCP/IP 应用层与应用程序

    TCP/IP 起源于二十世纪 60 年代末美国政府资助的一个分组交换网络研究项目,它是一个真正的开放协议,很多不同厂家生产各种型号的计算机,它们运行完全不同的操作系统,但 TCP/IP 协议组件允许它们互相进行通信。现在 TCP/IP 已经从一个只供一些科学家使用的小实验网成长为一个由成千上万的计算机和用户构成的全球化网络,TCP/IP 也已成为全球因特网(Internet)的基础,越来越多的 TCP/IP 互联网应用和企业商业应用正在改变着世界。

    TCP/IP 通讯协议采用了四层的层级模型结构(注:这与 OSI 七层模型不相同),每一层都调用它的下一层所提供的网络任务来完成自己的需求。TCP/IP 的每一层都是由一系列协议来定义的。这 4 层分别为:

     

    • 应用层 (Application):应用层是个很广泛的概念,有一些基本相同的系统级 TCP/IP 应用以及应用协议,也有许多的企业商业应用和互联网应用。
    • 传输层 (Transport):传输层包括 UDP 和 TCP,UDP 几乎不对报文进行检查,而 TCP 提供传输保证。
    • 网络层 (Network):网络层协议由一系列协议组成,包括 ICMP、IGMP、RIP、OSPF、IP(v4,v6) 等。
    • 链路层 (Link):又称为物理数据网络接口层,负责报文传输。

    图1显示了 TCP/IP 层级模型结构,应用层之间的协议通过逐级调用传输层(Transport layer)、网络层(Network Layer)和物理数据链路层(Physical Data Link)而可以实现应用层的应用程序通信互联。

    应用层需要关心应用程序的逻辑细节,而不是数据在网络中的传输活动。应用层其下三层则处理真正的通信细节。在 Internet 整个发展过程中的所有思想和着重点都以一种称为 RFC(Request For Comments)的文档格式存在。针对每一种特定的 TCP/IP 应用,有相应的 RFC 文档。一些典型的 TCP/IP 应用有 FTP、Telnet、SMTP、SNTP、REXEC、TFTP、LPD、SNMP、NFS、INETD 等。RFC 使一些基本相同的 TCP/IP 应用程序实现了标准化,从而使得不同厂家开发的应用程序可以互相通信。

    图 1 TCP/IP 层级模型结构
    图 1 TCP/IP 层级模型结构

    然而除了这些已经实现标准化的系统级 TCP/IP 应用程序外,在企业商业应用和互联网应用开发中,存在着大量的商业应用程序通信互联问题。如图 1 显示,其中的应用层所包含应用程序主要可以分成两类,即系统级应用和商业应用,互联网商业应用是商业应用中的主要形式之一。

    不同开发商和用户在开发各自商业应用通信程序时也存在有许多不同的设计方式。关于 TCP/IP 应用层以下的技术文献与书籍早已是汗牛充栋,但是关于 TCP/IP 应用本身,尤其是关于商业应用的通信设计模式技术讨论方面的文章还是比较少的。TCP/IP 应用通信设计模式实际上是在 TCP/IP 基础编程之上的一种应用编程设计方式,也属于一种应用层协议范畴,其可以包含有 TCP/IP 地址族模式设计、I/O 模式设计、通信连接模式设计以及通信数据格式设计等。鉴于目前讨论 TCP/IP 商业应用程序设计模式问题这方面的文章还很少见,本文尝试给出一些通信连接模式设计中共同的概念与一些典型的设计模式,在以后的文章中将继续讨论地址族模式设计、I/O 模式设计、以及通信数据格式设计等方面的模式设计实现话题。

    通信连接模式设计主要考虑内容有:

    • 通信两端程序建立通信方式
    • 通信连接方式
    • 通信报文发送与接收方式

    以下内容将介绍建立通信的 Client/Server 模型,然后逐一介绍通信连接模式设计所需要考虑的这些内容。


    传输层接口 APIs 与 TCP/IP 应用程序 C/S 模型

    传输层接口 APIs

    TCP/IP 应用层位于传输层之上,TCP/IP 应用程序需要调用传输层的接口才能实现应用程序之间通信。目前使用最广泛的传输层的应用编程接口是套接字接口(Socket)。Socket APIs 是于 1983 年在 Berkeley Socket Distribution (BSD) Unix 中引进的。 1986 年 AT&T 公司引进了另一种不同的网络层编程接口 TLI(Transport Layer Interface),1988 年 AT&T 发布了一种修改版的 TLI,叫做 XTI(X/open Transport interface)。XTI/TLI 和 Socket 是用来处理相同任务的不同方法。关于 TCP/IP APIs 使用文章与书籍已相当多,本文则是侧重于如何组合使用这些 APIs 来进行 TCP/IP 应用程序连接模式设计,并归纳出几种基本应用连接模式。

    如图 2 显示,应用层是通过调用传输层接口 APIs(Socket 或 XTI/TLI)来与传输层和网络层进行通信的。

    图 2 传输层接口
    图 2 传输层接口

    不管是使用何种编程接口,要在两个机器或两个程序之间建立通信,通信双方必须建立互相一致的通信模式。如果双方的通信设计模式不一致就无法建立有效的通信连接。

    以下是经常使用的 socket APIs,是建立 TCP/IP 应用程序的标准接口,也是影响 TCP/IP 应用程序通信方式的几个主要 APIs,不同 APIs 组合再结合系统调用可以实现不同方式的应用。Sockets 支持多种传输层和网络层协议,支持面向连接和无连接的数据传输,允许应用分布式工作。

    • socket():是用来创建一个 socket,socket 表示通信中的一个节点,其可以在一个网络中被命名,用 socket 描述符表示,socket 描述符类似于 Unix 中的文件描述符。
    • bind():是用来把本地 IP 层地址和 TCP 层端口赋予 socket。
    • listen() :把未连接的 socket 转化成一个等待可连接的 socket,允许该 socket 可以被请求连接,并指定该 socket 允许的最大连接数。
    • accept():是等待一个连接的进入,连接成功后,产生一个新的 socket 描述符,这个新的描述符用来建立与客户端的连接。
    • connect():用来建立一个与服务端的连接。
    • send():发送一个数据缓冲区,类似 Unix 的文件函数 write()。另外 sendto() 是用在无连接的 UDP 程序中,用来发送自带寻址信息的数据包。
    • recv():接收一个数据缓冲区,类似 Unix 的文件函数 readI()。另外 recvfrom() 是用在无连接的 UDP 程序中,用来接收自带寻址信息的数据包。
    • close():关闭一个连接

    Client/Server 模型

    Sockets 是以 Client 和 Server 交互通信方式来使用的。典型的系统配置是把 Server 放在一台机器中,而把 Client 放在另一台机器中,Client 连接到 Server 交换信息。一个 socket 有一系列典型的事件流。例如,在面向连接的 Client/Server 模型中,Server 端的 socket 总是等待一个 Client 端的请求。要实现这个请求,Server 端首先需要建立能够被 Client 使用的地址,当地址建立后,Server 等待 Client 请求服务。当一个 Client 通过 socket 连接到 Server 后,Client 与 Server 之间就可以进行信息交换。Client/Server 是通信程序设计的基本模式。从软件开发的角度讲,TCP/IP 应用程序都是基于 Client/Server 方式的。注意本篇文章以下 Client/Server 概念是针对程序内部调用 Socket API 所讲的概念,与针对整个程序甚至针对机器而讲的客户端 / 服务器概念有所不同。用 Server APIs 建立的程序可以被当作客户端使用,用 Client APIs 建立的程序也可以被用作服务器端使用。建立 Server 需要的 APIs 有 socket(), bind(), listen(), accept(),建立 Client 需要的 APIs 有 Socket(), Connect()。在实际应用开发中,同一个程序里往往同时可以有 Client 和 Server 的代码,或者多种形式的组合。在实际应用编程中,针对 Socket APIs 不同有效组合,结合系统调用可以有多种复杂的设计变化。

    面向连接的应用编程存在三类基本的不同级别的设计方式范畴,根据 Socket APIs 从上到下顺序依次是:

    • Client/Server 通信建立方式
    • Client/Server 通信连接方式
    • Client/Server 通信发送与接收方式

    下面内容以面向连接的 Socket 应用编程为例来说明这几种不同通信范畴的设计实现。


    Client/Server 建立方式设计概述

    一个 Client 连接一个 Server

    如果只有两台机器之间连接,那么一个是 Client,另一个是 Server,如下面图 3 所示。这是最简单的 TCP/IP 的应用,也是 TCP/IP 应用早期的 Peer to Peer (P2P) 概念。其流程基本如图 4 所示。

    图 3 TCP/IP 应用单点 Client/Server
    图 3 TCP/IP 应用单点 Client/Server

    图 4 显示了 TCP/IP 应用编程最基本的 Client/Server 模式,显示了基本的 Client/Server 通信所需要调用的 Socket APIs 以及顺序。

    图 4 TCP/IP 应用编程基本 Client/Server 模式
    图 4 TCP/IP 应用编程基本 Client/Server 模式

    多个 Client 连接一个 Server

    多个 Client 同时连接一个 Server 是 TCP/IP 应用的主流形式,如图 5 所示,其中 Client 连接数可以从几个到成千上万。

    图 5 TCP/IP 应用多 Client 端的 Client/Server
    图 5 TCP/IP 应用多 Client 端的 Client/Server

    由于 socket APIs 缺省方式下都是阻塞方式的,实现多个 Client 同时连接一个 Server 就需要特别的设计。其实现方式可以有多种不同的设计,这其中也涉及 I/O 模式设计。下面将展开介绍其中几种设计形式。

    利用一个 Client 连接一个 Server 形式实现多 Client 连接

    从程序设计角度讲,只要 Client 和 Server 端口是一对一形式,那么就属于一个 Client 连接一个 Server 形式。在处理多个 Client 端连接时,Server 端轮流使用多个端口建立多个 Client-Server 连接,连接关闭后,被释放端口可以被循环使用。在这种多连接形式中需要谨慎处理 Client 端如何获取使用 Server 端的可用端口。比如图 6 显示 Server 有一个服务于所有进程的进程可以先把 Server 端的可用端口发送给 Client 端,Client 端再使用该端口建立连接来处理业务。Server 针对每一个 Client 连接用一个专门的进程来处理。由于可用端口数有限,Server 用一个有限循环来处理每一个可用的端口连接。由于新端口需要用 bind() 来绑定,所以需要从 bind() 开始到 close() 结束都需要包含在循环体内。

    图 6 利用一对一 Client-Server 模式实现多 Client 连接
    图 6 利用一对一 Client-Server 模式实现多 Client 连接

    使用多个 accept() 实现多 Client 连接

    多进程 Server 一般有一个专注进程是服务于每一个连接的。当 Client 端完成连接后,专注进程可以循环被另外的连接使用。使用多个 accept() 也可以实现处理多 Client 连接。多 accept() 的 Server 也只有一个 socket(),一个 bind(),一个 listen(),这与通常情况一样。但是它建立许多工作子进程,每一个工作子进程都有 accept(),这样可以为每一个 Client 建立 socket 描述符。如图 7 所示,由于 accept() 连接成功后,会产生一个新的 socket 描述符,这样通过循环多进程利用 accept() 产生的多 socket 描述符就可以与多个 Client 进行连接通信。循环体是从 accept() 开始到 close() 结束的。

    图 7 使用多 accept() 实现多 Client 连接
    图 7 使用多 accept() 实现多 Client 连接

    使用并发 Server 模式实现多 Client 连接

    并发服务器模式曾经是 TCP/IP 的主流应用程序设计模式,得到广泛使用,目前互联网上仍有相当多的应用使用此种模式。其设计思路是在 accept 之后 fork 出一个子进程。因为 socket 会产生监听 socket 描述符 listenfd,accept 会产生连接 socket 描述符 connfd。连接建立后,子进程继承连接描述符服务于 Client,父进程则继续使用监听描述符等待另外一个 Client 的连接请求,以产生另外一个连接 socket 描述符和子进程。如图 8 所示,accept() 接收到一个 Client 连接后,产生一个新的 socket 描述符,通过 fork() 系统调用,用一个子进程来处理该 socket 描述符的连接服务。而父进程可以立即返回到 accept(),等待一个新的 Client 请求,这就是典型的并发服务器模式。并发服务器模式同时处理的最大并发 Client 连接数由 listen() 的第二个参数来指定。

    图 8 TCP/IP 应用并发 Server
    图 8 TCP/IP 应用并发 Server

    使用 I/O 多路技术实现多 Client 连接

    以上三种连接设计,多 Server 端口、多 accept() 和并发服务器模式,都是通过 fork() 系统调用产生多进程来实现多 Client 连接的。使用 I/O 多路技术也可以同时处理多个输入与输出问题,即用一个进程同时处理多个文件描述符。I/O 多路技术是通过 select() 或 poll() 系统调用实现的。poll() 与 select() 功能完全相同,但是 poll() 可以更少使用内存资源以及有更少的错误发生。select() 调用需要与操作文件描述符集的 APIs 配合使用。select() 系统调用可以使一个进程检测多个等待的 I/O 是否准备好,当没有设备准备好时,select() 处于阻塞状态中,其中任一设备准备好后,select() 函数返回调用。select() API 本身也有一个超时时间参数,超时时间到后,无论是否有设备准备好,都返回调用。其流程如图 9 所示。在 socket APIs listen() 和 accept() 之间插入 select() 调用。使用这三个宏 FD_ZERO()、FD_CLR() 和 FD_SET(),在调用 select() 前设置 socket 描述符屏蔽位,在调用 select() 后使用 FD_ISSET 来检测 socket 描述符集中对应于 socket 描述符的位是否被设置。 FD_ISSET() 就相当通知了一个 socket 描述符是否可以被使用,如果该 socket 描述符可用,则可对该 socket 描述符进行读写通信操作。通常,操作系统通过宏 FD_SETSIZE 来声明在一个进程中 select() 所能操作的文件或 socket 描述符的最大数目。更详细的 I/O 多路技术实现,可以参考其他相关文献。

    图 9 I/O 多路技术实现多连接的 Server
    图 9 I/O 多路技术实现多连接的 Server

    一个 Client 连接多个 Server

    一个 Client 连接多个 Server 这种方式很少见,主要用于一个客户需要向多个服务器发送请求情况,比如一个 Client 端扫描连接多个 Server 端情况。如图 10 所示。此种方式设计主要是 Client 端应用程序的逻辑设计,通常需要在 Client 端设计逻辑循环来连接多个 Server,在此不做更多描述。

    图 10 单 Client 对多 Server
    图 10 单 Client 对多 Server

    复杂 Client/Server 设计与现代 P2P

    最近几年,对等网络技术 ( Peer-to-Peer,简称 P2P) 迅速成为计算机界关注的热门话题之一,以及影响 Internet 未来的科技之一。与早期点对点 (Peer to Peer) 的 Client/Server 模式不同,现在的 P2P 模式是指每个结点既可充当服务器,为其他结点提供服务,同时也可作为客户端享用其他结点提供的服务。实际上 P2P 模式仍然是基于 Client/Server 模式的,每个通信节点都既是 Server,又是 Client,P2P 是基于复杂 Client/Server 设计的 TCP/IP 应用。图 11 显示 P2P 模式下两个用户 PC 之间的对等连接。

    图 11 P2P 模式
    图 11 P2P 模式

    在技术上,P2P 本身是基于 TCP/IP Client/Server 技术的一种设计模式思想, P2P 也属于网络应用层技术,与 Web 和 FTP 等应用是并列的。只是 P2P 应用在设计实现上更要复杂的多。P2P 技术实现的协同工作是无需专门的服务器支持的 (Serverless),这里的服务器概念与 Client/Server 中的 Server 概念是不一样的。在传统意义上中心服务器机器上往往运行的是 TCP/IP 应用的 Server 端程序,所以传统意义上的 Server 概念在机器与应用上是重合的。如果更改 TCP/IP 的应用设计,使应用程序既可做 Server 又可做 Client,就可以实现无中心服务器的 P2P 模式。

    在设计模式上,P2P 模式实现了网络终端用户不依赖中心服务器或者服务商而直接进行信息和数据交换的可能,因此 P2P 正在改变着整个互联网的一些基础应用,从而极大地增加了用户之间的信息沟通和交流能力。目前互联网的 P2P 应用与网络都正在飞速发展,一些典型的 P2P 应用程序比如有 BitTorrent, eDonkey 等,另外一些即时通信(IM)类软件比如 MSN、QQ 等也正在向无中心服务器模式转变。无中心服务器的 Internet 应用程序大大降低应用提供商的运营成本,而且减少人们对于 Server 稳定性的依赖。


    Client/Server 通信连接方式设计

    Client/Server 通信方式建立后,下一步就需要考虑通信连接的方式,主要有两种方式的连接,即长连接通信与短连接通信。通信连接方式涉及到的 APIs 主要是 connect() 和 accept()。要实现某种 Client/Server 方式,就必须考虑用某种特定的连接方式。

    短连接通信

    短连接通信是指 Client 方与 Server 方每进行一次通信报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此种方式常用于多个 Client 连接一个 Server 情况,常用于机构与用户之间通信,比如 OLTP(联机事务处理)类应用。在短连接情况下,Client 端完成任务后,就关闭连接并退出。在 Server 端,可以通过循环 accept(),使 Server 不会退出,并连续处理 Client 的请求。图 12 显示了一般情况下短连接通信模式的 Socket 事件流,不同设计的连接多 Client 的 Server 有不同的循环流程。

    图 12 短连接模式通信
    图 12 短连接模式通信

    长连接通信

    长连接通信是指 Client 方与 Server 方先建立通讯连接,连接建立后不会断开,然后再进行报文发送和接收,报文发送与接收完毕后,原来连接不会断开而继续存在,因此可以连续进行交易报文的发送与接收。这种方式下由于通讯连接一直存在,其 TCP/IP 状态是 Established,可以用操作系统的命令 netstat 查看连接是否建立。由于在长连接情况下,Client 端和 Server 端一样可以固定使用一个端口,所以长连接下的 Client 也需要使用 bind() 来绑定 Client 的端口。在长连接方式下,需要循环读写通信数据。为了区分每一次交易的通信数据,每一次交易数据常常需要在数据头部指定该次交易的长度,接收 API 需要首先读出该长度,然后再按该长度读出指定长度的字节。长连接方式常用于一个 Client 端对一个 Server 端的通讯,一般常用于机构与机构之间的商业应用通信,以处理机构之间连续的大量的信息数据交换。或者说可用于两个系统之间持续的信息交流情况。通常为了加快两个系统之间的信息交流,通常还需要建立几条长连接的并行通信线路。图 13 显示了一般情况下长连接通信模式的 socket 事件流,可见其最大特点是 Client 和 Server 都有循环体,而且循环体只包含读写 APIs。

    图 13 长连接模式通信
    图 13 长连接模式通信

    Client/Server 通信发送与接收方式设计

    在通信数据发送与接收之间也存在不同的方式,即同步和异步两种方式。这里的同步和异步与 I/O 层次的同异步概念不同。主要涉及 socket APIs recv() 和 send() 的不同组合方式。

    同步发送与接收

    从应用程序设计的角度讲,报文发送和接收是同步进行的,既报文发送后,发送方等待接收方返回消息报文。同步方式一般需要考虑超时问题,即报文发出去后发送方不能无限等待,需要设定超时时间,超过该时间后发送方不再处于等待状态中,而直接被通知超时返回。同步发送与接收经常与短连接通信方式结合使用,称为同步短连接通信方式,其 socket 事件流程可如上面的图 12 所示。

    异步发送与接收

    从应用程序设计的角度讲,发送方只管发送数据,不需要等待接收任何返回数据,而接收方只管接收数据,这就是应用层的异步发送与接收方式。要实现异步方式,通常情况下报文发送和接收是用两个不同的进程来分别处理的,即发送与接收是分开的,相互独立的,互不影响。异步发送与接收经常与长连接通信方式结合使用,称为异步长连接通信方式。从应用逻辑角度讲,这种方式又可分双工和单工两种情况。

    异步双工

    异步双工是指应用通信的接收和发送在同一个程序中,而有两个不同的子进程分别负责发送和接收,异步双工模式是比较复杂的一种通信方式,有时候经常会出现在不同机构之间的两套系统之间的通信。比如银行与银行之间的信息交流。它也可以适用在现代 P2P 程序中。如图 14 所示,Server 和 Client 端分别 fork 出两个子进程,形成两对子进程之间的连接,两个连接都是单向的,一个连接是用于发送,另一个连接用于接收,这样方式的连接就被称为异步双工方式连接。

    图 14 长连接异步双工模式
    图 14 长连接异步双工模式

    异步单工

    应用通信的接收和发送是用两个不同的程序来完成,这种异步是利用两对不同程序依靠应用逻辑来实现的。图 15 显示了长连接方式下的异步单工模式,在通信的 A 和 B 端,分别有两套 Server 和 Client 程序,B 端的 Client 连接 A 端的 Server,A 端的 Server 只负责接收 B 端 Client 发送的报文。A 端的 Client 连接 B 端的 Server,A 端 Client 只负责向 B 端 Server 发送报文。

    图 15 长连接异步单工模式
    图 15 长连接异步单工模式

    典型通信连接模式

    综上所述,在实际 TCP/IP 应用程序设计中,就连接模式而言,我们需要考虑 Client/Server 建立方式、Client/Server 连接方式、Client/Server 发送与接收方式这三个不同级别的设计方式。实际 TCP/IP 应用程序连接模式可以是以上三类不同级别 Client/Server 方式的组合。比如一般 TCP/IP 相关书籍上提供的 TCP/IP 范例程序大都是同步短连接的 Client/Server 程序。有的组合是基本没有实用价值的,比较常用的有价值的组合是以下几种:

    • 同步短连接 Server/Client
    • 同步长连接 Server/Client
    • 异步短连接 Server/Client
    • 异步长连接双工 Server/Client
    • 异步长连接单工 Server/Client

    其中异步长连接双工是较为复杂的一种通信方式,有时候经常会出现在不同银行或不同城市之间的两套系统之间的通信,比如国家金卡工程。由于这几种通信方式比较固定,所以可以预先编制这几种通信方式的模板程序。


    总结

    本文探讨了 TCP/IP 应用程序中连接模式的设计。在以后的文章中还将继续讨论 TCP/IP 应用程序设计中的其他方面的设计话题,包括地址族模式设计、I/O 模式设计、以及通信数据格式设计等。

    展开全文
  • 本文的作者通过分析 TCP/IP 程序在不同级别上采用的不同方式来向您讲述了如何设计好 TCP/IP 应用程序的通信模式以及需要注意的相关问题。
  • TCP应用程序通信协议的处理

    千次阅读 2015-06-29 23:25:23
    TCP应用程序通信协议的处理flyfish 2015-6-29一 流式处理 TCP是一种流协议(stream protocol)。TCP数据是以字节流的形式传递给接收者的,没有固有的”报文”或”报文边界”或者用户可见的”分组”的概念。 它只是...

    TCP应用程序通信协议的处理

    flyfish 2015-6-29

    一 流式处理
    TCP是一种流协议(stream protocol)。TCP数据是以字节流的形式传递给接收者的,没有固有的”报文”或”报文边界”或者用户可见的”分组”的概念。
    它只是传送了一个字节流,我们无法准确地预测在一个特定的读操作中会返回多少字节。尽管网络层数据在节点之间是以IP分组的形式传输的,但分组中的数据量与send调用中传送给TCP多少数据并没有直接关系。而且,接收程序也没有什么可靠的方法可以判断数据是如何分组的,因为在两次recv调用之间可能会有多个分组到来。如果你的应用程序的设计与TCP对数据的分组方式有所关联,那么请重新设计应用程序。
    处理”粘包”,“分包”正是因为错误了理解了TCP数据传输模型,当以字节流处理时这个问题就不存在了。

    二 检测客户端是否在线
    因为TCP无法将连接的丢失立即通知应用程序
    TCP有一种保持活跃(keep-alive)的机制可以用来检测死连接,但这对应用程序来说,通常没什么用处。保持活跃机制并没有真正成为连接监测机制的主要原因之一就是默认的时间区间太长了。

    可以使用检测方式比较灵活
    1 心跳检测:客户端直接发送给服务器“我在线”的信息
    2 心跳检测:客户端连接到服务器之后,会向服务器发送一个端口号,之后在这个端口上监听来自服务器的心跳连接
    3 在读操作上设置一个定时器,这样的话,如果客户端在某段时间区间内没有发出请求,服务器就假定客户端已经不存在了

    三 采用防御性编程以防止客户端的不友好操作

    1检验客户端的有效数据,防止发生非预期行为。
    2检查缓冲区的溢出情况

    参考《TCP/IP高效编程:改善网络程序的44个技巧》

    展开全文
  • 基于TCP的 C/S模式 网络应用程序

    千次阅读 2013-07-20 08:38:40
    服务器端程序实现步骤: 1。创建套接字(socket)。 2。将套接字绑定到一个本地地址和端口上(bind)。 3。将套接字设为监听模式,准本接受客户请求(listen)。 4。等待客户请求到来;当请求到来后,...

    服务器端程序实现步骤:

    1。创建套接字(socket)。

    2。将套接字绑定到一个本地地址和端口上(bind)。

    3。将套接字设为监听模式,准本接受客户请求(listen)。

    4。等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。

    5。用返回的套接字和客户端进行通信(send / recv)。

    6。返回,等待另一个客户请求。

    7。关闭套接字。

    服务器端代码:

    #include<Winsock2.h>
    #include<stdio.h>
    
    void main()
    {
    	//加载Windows Socket库
    	WORD wVersionRequested;
    	WSADATA wsaData;
    	int err;
    	
    	wVersionRequested = MAKEWORD( 1, 1 );
    	
    	err = WSAStartup( wVersionRequested, &wsaData );
    	if ( err != 0 ) {
    		return;
    	}
    	
    	if ( LOBYTE( wsaData.wVersion ) != 1 ||
            HIBYTE( wsaData.wVersion ) != 1 ) {
    		WSACleanup( );
    		return; 
    	}
    
    	SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
    
    	SOCKADDR_IN addrSrv;
    	addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
    	addrSrv.sin_family=AF_INET;
    	addrSrv.sin_port=htons(6000);
    	bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
    
    	listen(sockSrv,5);
    
    	SOCKADDR_IN addrClient;
    	int len=sizeof(SOCKADDR);
    
    	while(1)
    	{
    		SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
    		
    		char sendBuf[100];
    		sprintf(sendBuf,"Welcome %s to http://blog.csdn.net/Crazy_xiaohe"
    			,inet_ntoa(addrClient.sin_addr));
    		send(sockConn,sendBuf,strlen(sendBuf)+1,0);
    		
    		char recvBuf[100];
    		recv(sockConn,recvBuf,100,0);
    		printf("%s\n",recvBuf);
    		
    		closesocket(sockConn);
    	}
    }

    客户端程序实现步骤:

    1。创建套接字(socket)。

    2。向服务器发送连接请求(connect)。

    3。和服务器端进行通信(send / recv)。

    4。关闭套接字。

    客户端代码:

    #include<Winsock2.h>
    #include<stdio.h>
    
    void main()
    {
    	//加载Windows Socket库
    	WORD wVersionRequested;
    	WSADATA wsaData;
    	int err;
    	
    	wVersionRequested = MAKEWORD( 1, 1 );
    	
    	err = WSAStartup( wVersionRequested, &wsaData );
    	if ( err != 0 ) {
    		return;
    	}
    	
    	if ( LOBYTE( wsaData.wVersion ) != 1 ||
            HIBYTE( wsaData.wVersion ) != 1 ) {
    		WSACleanup( );
    		return; 
    	}
    
    	SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
    
    	SOCKADDR_IN addrSrv;
    	addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    	addrSrv.sin_family=AF_INET;
    	addrSrv.sin_port=htons(6000);
    	connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
    
    	char recvBuf[100];
    	recv(sockClient,recvBuf,100,0);
    	printf("%s\n",recvBuf);
    	
    	send(sockClient,"This is xiaohe",strlen("This is xiaohe")+1,0);
    
    	closesocket(sockClient);
    	
    	WSACleanup();	
    }

    PS:注意加入工程连接 ws2_32.lib

    展开全文
  • 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量 的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个...
    1、修改用户进程可打开文件数限制

    在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量 的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。可使用ulimit命令查看系统允许 当前用户进程打开的文件数限制:
    [speng@as4 ~]$ ulimit -n
    1024
    这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件,那么剩下的可用于客户端socket连接的文件数就只有大概1024-10=1014个左右。 也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014个TCP并发连接。

    对于想支持更高数量的TCP并发连接的通讯处理程序,就必须修改Linux对当前用户的进程同时打开的文件数量的软限制(soft limit)和硬限制(hardlimit)。其中软限制是指Linux在当前系统能够承受的范围内进一步限制用户同时打开的文件数;硬限制则是根据系统 硬件资源状况(主要是系统内存)计算出来的系统最多可同时打开的文件数量。通常软限制小于或等于硬限制。

    修改上述限制的最简单的办法就是使用ulimit命令:
    [speng@as4 ~]$ ulimit -n <file_num>
    上述命令中,在<file_num>中指定要设置的单一进程允许打开的最大文件数。如果系统回显类似于“Operation notpermitted”之类的话,说明上述限制修改失败,实际上是因为在<file_num>中指定的数值超过了Linux系统对该用户 打开文件数的软限制或硬限制。因此,就需要修改Linux系统对用户的关于打开文件数的软限制和硬限制。

    第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
    speng soft nofile 10240
    speng hard nofile 10240
    其中speng指定了要修改哪个用户的打开文件数限制,可用'*'号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;10240则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。

    第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
    session required /lib/security/pam_limits.so
    这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开 的最大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。修改 完后保存此文件。

    第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
    [speng@as4 ~]$ cat /proc/sys/fs/file-max
    12158
    这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)12158个文件,是Linux系统级硬限制,所有用户级的打开文件数限制 都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不 应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。修改此硬限制的方法是修改/etc/rc.local脚本,在脚本中添加如下行:
    echo 22158 > /proc/sys/fs/file-max
    这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为22158。修改完后保存此文件。

    完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用 ulimit-n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用 ulimit-n命令已经将用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于 或等于上次ulimit-n设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文 件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文 件,用户退出并重新登录系统即可。
    通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。

    2、修改网络内核对TCP连接的有关限制

    在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。

    第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返 回失败,查看系统错误提示消息是“Can't assign requestedaddress”。同时,如果在此时用tcpdump工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况 说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的 本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每 个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此 时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can't assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
    static int tcp_v4_hash_connect(struct sock *sk)
    请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:
    void __init tcp_init(void)
    内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。
    第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
    net.ipv4.ip_local_port_range = 1024 65000
    这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。
    第二步,执行sysctl命令:
    [speng@as4 ~]$ sysctl -p
    如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。

    第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库 的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用 中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
    第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
    net.ipv4.ip_conntrack_max = 10240
    这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。
    第二步,执行sysctl命令:
    [speng@as4 ~]$ sysctl -p
    如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。

    3、使用支持高并发网络I/O的编程技术

    在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。

    可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞 程序的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步I /O是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机 制。异步I/O的技术就是使用AIO。

    从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是 不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部 分TCP连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每个I /O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到 改进)。

    综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。


    1、修改用户进程可打开文件数限制

    在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的 并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也 是一个文件句柄)。可使用ulimit命令查看系统允许当前用户进程打开的文件数限制:
    [speng@as4 ~]$ ulimit -n
    1024
    这 表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件,那么剩下的可用于客户端socket连接的文件数就只有大概1024-10=1014个左右。 也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014个TCP并发连接。

    对于想支持更高数量的TCP并发连接的通讯 处理程序,就必须修改Linux对当前用户的进程同时打开的文件数量的软限制(soft limit)和硬限制(hardlimit)。其中软限制是指Linux在当前系统能够承受的范围内进一步限制用户同时打开的文件数;硬限制则是根据系统 硬件资源状况(主要是系统内存)计算出来的系统最多可同时打开的文件数量。通常软限制小于或等于硬限制。

    修改上述限制的最简单的办法就是使用ulimit命令:
    [speng@as4 ~]$ ulimit -n <file_num>
    上 述命令中,在<file_num>中指定要设置的单一进程允许打开的最大文件数。如果系统回显类似于“Operation notpermitted”之类的话,说明上述限制修改失败,实际上是因为在<file_num>中指定的数值超过了Linux系统对该用户 打开文件数的软限制或硬限制。因此,就需要修改Linux系统对用户的关于打开文件数的软限制和硬限制。

    第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
    speng soft nofile 10240
    speng hard nofile 10240
    其中speng指定了要修改哪个用户的打开文件数限制,可用'*'号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;10240则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。

    第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
    session required /lib/security/pam_limits.so
    这 是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的最 大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。修改完后 保存此文件。

    第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
    [speng@as4 ~]$ cat /proc/sys/fs/file-max
    12158
    这 表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)12158个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不 应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该 修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。修改此硬限制的方法是修改/etc/rc.local脚本,在脚本中添加如下行:
    echo 22158 > /proc/sys/fs/file-max
    这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为22158。修改完后保存此文件。

    完 成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用ulimit- n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit-n命令已经将 用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次ulimit-n 设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了 ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统 即可。
    通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。

    2、修改网络内核对TCP连接的有关限制

    在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。

    第 一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返回失 败,查看系统错误提示消息是“Can't assign requestedaddress”。同时,如果在此时用tcpdump工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况 说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的 本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每 个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此 时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can't assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
    static int tcp_v4_hash_connect(struct sock *sk)
    请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:
    void __init tcp_init(void)
    内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。
    第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
    net.ipv4.ip_local_port_range = 1024 65000
    这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。
    第二步,执行sysctl命令:
    [speng@as4 ~]$ sysctl -p
    如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。

    第 二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库 的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用 中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
    第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
    net.ipv4.ip_conntrack_max = 10240
    这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。
    第二步,执行sysctl命令:
    [speng@as4 ~]$ sysctl -p
    如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。

    3、使用支持高并发网络I/O的编程技术

    在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。

    可 用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞程序 的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步I/O 是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异 步I/O的技术就是使用AIO。

    从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常 在1024个以内)。如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运 行效率相当低,并可能存在I/O事件分派不均,导致部分TCP连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期 Linux内核的AIO技术实现是通过在内核中为每个I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问 题。但在最新的Linux内核中,AIO的实现已经得到改进)。

    综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。
    展开全文
  • 在做网管系统系统设计 时,考虑到要分布式,以及多层数据交换,评估监控的主机量 会随着运营商每年的投入增加,现需要监控的机器数量都已经到500多台,除了采用SNMP协议外,还涉及了业务系统的监控数据交互,这2者都...
  • 登陆采用TCP协议和HTTP协议,你和好友之间发送消息,主要采用UDP协议,内网传文件采用了P2P技术。 QQ对于普通用户是采用UDP协议,对于会员用TCP协议 总来的说: 1.登陆过程,客户端client 采用TCP协议向服务器...
  • C #应用SOCKET实现TCP/IP协议的通讯

    千次阅读 2017-10-29 23:29:03
    C#学习TCP/IP之SOCKET通信应用基本知识OSI七层网络...图1-1 网络模型而TCP/IP通讯协议采用了4层的层级结构,IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层。socket则是对TCP/IP协议的封装和应用
  • C#网络编程TCP通信实例程序简单设计

    万次阅读 多人点赞 2017-04-20 10:08:37
    采用自带TcpClient和TcpListener设计一个Tcp通信的例子 只实现了TCP通信 通信程序截图: 压力测试服务端截图: 俩个客户端链接服务端测试截图: 服务端: 客户端 运行动态图 C#程序设计代码 ...
  • TCP应用层主要协议

    千次阅读 2015-09-27 21:51:05
    TCP/IP应用层对应了OSI参考模型的上三层(会话层、表示...是由哪个应用程序发出的。应用层主要包括一下协议:  文件传输类:HTTP、FTP、TFTP;  远程登录类:Telnet;  电子邮件类:SMTP;  网络管理类:SNMP;
  • TCP 详解

    万次阅读 多人点赞 2018-06-20 00:30:36
    上回说到 UDP 协议, 与之对应的便是 TCP 协议 TCP协议 TCP协议全称: 传输控制协议, 顾名思义, 就是要对数据的传输进行一定的控制. 先来看看它的报头 我们来分析分析每部分的含义和作用 源端口号/目的端口号:...
  • WindowsSockets基础—TCP,UDP程序

    千次阅读 2013-05-23 00:37:58
    TCP程序 TCPServer// TCPServer.cpp : 定义控制台应用程序的入口点。 //接收客户的发来的"MyTCP" #include &lt;stdio.h&gt; #include &lt;WinSock2.h&gt; #pragma comment(lib,"ws2...
  • C#.Net网络程序开发-Tcp

    千次阅读 2006-01-06 12:31:00
    前一篇《Visual C#.Net网络程序开发-Socket篇》中说到:支持Http、Tcp和Udp的类组成了TCP/IP三层模型(请求响应层、应用协议层、传输层)的中间层-应用协议层,该层的类比位于最底层的Socket类提供了更高层次的抽象,...
  • TCP采用哪些机制来实现可靠数据传输、流控和拥塞控制? 1.采用面向连接的三次握手实现可靠对象传输。 2.使用数据窗口机制协商队列大小实现数据队列传输。 3.通过序列化应答和必要时重发数据包,TCP应用程序...
  • 一Web应用程序  (1)什么是Web应用程序  应用程序有两种模式C/S、B/S。C/S是客户端/服务器端程序,也就是说这类程序一般独立运行。而B/S就是浏览 器端/服务器端应用程序,这类应用程序一般借助浏览器来运行。 ...
  • Windows网络编程,相信好多人都知道,但是我们一般都是用其他语言编写,例如C,C++,JAVA,python等等,这些语言都可以,但是汇编语言比较底层,利用它,我们可以更清晰的...说道网络编程,现在我所接触到的程序开发,
  • VC++ TCP网络控制台程序

    万次阅读 2013-11-27 16:53:13
    在Windows7系统下,采用工具为VS2008,Win32控制台应用程序,编写一个基于TCP的Client/Server网络程序。 1、服务器端代码 #include #include #define SERVERPORT 6000 //服务端口号 int main(int argc, char *...
  • 一、基于TCP应用层协议有:SMTP、TELNET、HTTP、FTP 基于UDP的应用层协议:DNS、TFTP(简单文件传输协议)、RIP(路由选择协议)、DHCP、BOOTP(是DHCP的前身)、IGMP(Internet组管理协议) ...
  • 使用netstat调试TCP应用

    千次阅读 2017-07-02 13:49:25
    首先要明确netstat是干嘛的:netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计...
  • 本文通过python3+PyQt5实现《python Qt GUI快速编程》第18章的例子Building Services application。本例分别创建一个TCP客户端和TCP服务器,采用PyQt的QtNetwork模块,而不是Python标准库或Twisted网络引擎。
  • TCP socket心跳包示例程序

    万次阅读 2016-05-06 03:11:35
    在做游戏开发时,经常需要在应用层实现自己的心跳机制,即定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性。在TCP socket心跳机制中,心跳包可以由服务器发送给客户端,也可以由...
  • TCP

    千次阅读 2015-06-15 08:33:25
    就是说,应用程序在使用TCP协议之前,必须先建立TCP连接。在数据传送完毕后,必须释放已经建立的TCP连接。 2. TCP连接只能是点对点的,也就是一对一,不同于UDP的一对多,多对多。 3. TCP是可靠传输,通过TCP传输...
  • 基本应用层的TCP/IP协议介绍 (HTTP/FTP/POP/SMTP)来源:http://www.networkdictionary.com/chinese/protocols/tcpip.php HTTP:超文本传输协议更详细的HTTP协议头信息参考我blog之前的文章。 HTTP:
  • TCP和UDP的最完整的区别

    万次阅读 多人点赞 2016-08-04 11:30:30
    TCP和UDP两种协议的比较汇总
  • TCP/IP入门(4) --应用

    千次阅读 2015-04-08 15:06:58
    /**本篇博客由汗青ZJF整理并发布, 转载请注明出处:http://blog.csdn.net/zjf280441589/article/category/1854365*/TCP/IP中的应用层 DNS简介 域名系统是基于描述名字-地址映射的分布式计算机系统的实现,其作用是...
  • 一个socket只能与一个socket地址绑定即一个socket只能监听一个端口,...现在服务器监听一个端口上的TCP和UDP请求,并将发送来的数据回射到客户端。 服务端程序: #include #include #include #include #includ
  • TCP 和 UDP 的区别

    万次阅读 多人点赞 2018-08-04 21:57:42
    前言 UDP TCP TCP 的三次握手 TCP 四次挥手 累计确认 顺序问题和丢包问题 流量控制的问题 拥塞控制的问题 ...前端的面试中经常问的 TCP 和 UDP 的区别,网上也有...UDP程序结构较简单 TCP 是面向字节流的,UDP 是基于...
  • 7.TCP和UDP的区别和应用场景

    千次阅读 2017-08-28 15:08:21
     3.UDP程序结构较简单   4.流模式(TCP)与数据报模式(UDP);   5.TCP保证数据正确性,UDP可能丢包   6.TCP保证数据顺序,UDP不保证    UDP应用场景:  1.面向数据报方式  2.网络数据大多为短消息   3
  • TCP报文格式

    万次阅读 2007-08-01 13:21:00
    用户应用程序采用首先调用TCP(或UDP),然后将应用程序数据递交给TCP这一方式,在IP网络上传送数据。TCP将这些数据打包分段并调用IP模块向目的主机传送每个数据段。接收方的TCP将段中的数据放入接收缓冲器,然后将...
  • 汽车以太网对TCP/IP协议簇的应用

    千次阅读 2019-03-05 14:48:05
    汽车以太网与传统以太网的主要区别在于物理层及应用层,而网络层及传输层大多参考传统应用,即TCP/IP协议簇(TSN暂不讨论)。使用传统网络TCP/IP协议簇,既能加快汽车以太网数据传输的速度,又能与因特网无缝连接,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 217,310
精华内容 86,924
关键字:

哪些应用程序采用tcp