020网站模板,怎样注册企业邮箱帐号,福建省建住房建设部网站,学生网站开发大赛1 网络通信概述
1.1 IP 和端口 所有的数据传输#xff0c;都有三个要素 #xff1a;源、目的、长度。 怎么表示源或者目的呢#xff1f;请看图 所以#xff0c;在网络传输中需要使用“IP 和端口”来表示源或目的。
1.2 网络传输中的 2 个对象#xff1a;server 和 cl…1 网络通信概述
1.1 IP 和端口 所有的数据传输都有三个要素 源、目的、长度。 怎么表示源或者目的呢请看图 所以在网络传输中需要使用“IP 和端口”来表示源或目的。
1.2 网络传输中的 2 个对象server 和 client 我们经常访问网站这涉及 2 个对象网站服务器浏览器。网站服务器平时安静地呆着浏览器主动发起数据请求。网站服务器、浏览器可以抽象成 2 个软件的概念server 程序、 client 程序。 1.3 两种传输方式TCP/UDP
在一般的网络书籍中网络协议被分为 5 层如图 应用层它是体系结构中的最高层直接为用户的应用进程例如电子邮件、文件传输和终端仿真提供服务。在因特网中的应用层协议很多如支持万维网应用的 HTTP 协议支持电子邮件的 SMTP 协议支持文件传送的 FTP 协议 DNS POP3 SNMP Telnet 等等。 运输层负责向两个主机中进程之间的通信提供服务。 运输层主要使用以下两种协议 传输控制协议 TCP(Transmission Control Protocol) 面向连接的数据传输的单位是报文段能够提供可靠的交付。 用户数据包协议 UDP(User Datagram Protocol) 无连接的数据传输的单位是用户数据报不保证提供可靠的交付只能提供“ 尽最大努力交付 ” 。 ⚫ 网络层负责将被称为数据包 datagram 的网络层分组从一台主机移动到另一台主机。 ⚫ 链路层因特网的网络层通过源和目的地之间的一系列路由器路由数据报。 ⚫ 物理层在物理层上所传数据的单位是比特。物理层的任务就是透明地传送比特流。 这些层对于初学者来说很难理解我们只需要知道我们需要使用“运输层” 编写应用程序我们的应用程序位于“应用层”。 使用“运输层”时可以选择 TCP 协议也可以选择 UDP 协议。 1.3.1 TCP 和 UDP 原理上的区别 TCP 向它的应用程序提供了面向连接的服务。这种服务有 2 个特点可靠传输、流量控制即发送方/ 接收方速率匹配。它包括了应用层报文划分为短报文并提供拥塞控制机制。 UDP 协议向它的应用程序提供无连接服务。它没有可靠性没有流量控制也没有拥塞控制。 1.3.2 为何存在 UDP 协议 既然 TCP 提供了可靠数据传输服务而 UDP 不能提供那么 TCP 是否总是首选呢 答案是否定的因为有许多应用更适合用 UDP 举个例子视频通话时使用 UDP 偶尔的丢包、偶尔的花屏时可以忍受的如果使用 TCP 每个数据包都要确保可靠传输当它出错时就重传这会导致后续的数据包被阻滞视频效果反而不好。 使用 UDP 时有如下特点 1.关于何时发送什么数据控制的更为精细 采用 UDP 时只要应用进程将数据传递给 UDP UDP 就会立即将其传递给网络层。而 TCP 有重传机制而不管可靠交付需要多长时间。但是实时应用通常不希望过分的延迟报文段的传送且能容忍一部分数据丢失。 2.无需建立连接不会引入建立连接时的延迟。 3.无连接状态能支持更多的活跃客户。 4.分组首部开销较小。 1.3.3 TCP/UDP 网络通信大概交互图 下面我们分别画出运用 TCP 协议和运用 UDP 协议的客户端和服务器大概交互图。 面向连接的 TCP 流模式 UDP 用户数据包模式 2 网络编程主要函数介绍
2.1 socket 函数
int socket(int domain, int type,int protocol); 此函数用于创建一个套接字。 ⚫ domain 是网络程序所在的主机采用的通讯协族 (AF_UNIX 和 AF_INET 等 ) 。 ◼ AF_UNIX 只能够用于单一的 Unix 系统进程间通信而 AF_INET 是针对 Internet 的因而可以允许远程通信使用。 ⚫ type 是网络程序所采用的通讯协议 (SOCK_STREAM,SOCK_DGRAM 等 ) 。 ◼ SOCK_STREAM 表明用的是 TCP 协议这样会提供按顺序的可靠双向面向连接的比特流。 ◼ SOCK_DGRAM 表明用的是 UDP 协议这样只会提不可靠无连接的通信。 ⚫ 关于 protocol 由于指定了 type 所以这个地方一般只要用 0 来代替就可以了。 此函数执行成功时返回文件描述符失败时返回-1, 看 errno 可知道出错的详细情况。 2.2 bind 函数
int bind(int sockfd, struct sockaddr *my_addr, int addrlen); 从函数用于将地址绑定到一个套接字。 ⚫ sockfd 是由 socket 函数调用返回的文件描述符。 ⚫ my_addr 是一个指向 sockaddr 的指针。 ⚫ addrlen 是 sockaddr 结构的长度。 sockaddr 的定义 struct sockaddr{unisgned short as_family;char sa_data[14];
}; 不 过 由 于 系 统 的 兼 容 性 , 我 们 一 般 使 用 另 外 一 个 结 构 (struct sockaddr_in) 来代替。 sockaddr_in 的定义 struct sockaddr_in{unsigned short sin_family;unsigned short sin_port;struct in_addr sin_addr;unsigned char sin_zero[8];
} 如果使用 Internet 所以 sin_family 一般为 AF_INET 。 ⚫ sin_addr 设置为 INADDR_ANY 表示可以和任何的主机通信。 ⚫ sin_port 是要监听的端口号。 ⚫ bind 将本地的端口同 socket 返回的文件描述符捆绑在一起 . 成功是返回 0,失败的情况和 socket 一样。 2.3 listen 函数
int listen(int sockfd,int backlog); 此函数宣告服务器可以接受连接请求。 ⚫ sockfd 是 bind 后的文件描述符。 ⚫ backlog 设置请求排队的最大长度。当有多个客户端程序和服务端相连时使用这个表示可以介绍的排队长度。 ⚫ listen 函数将 bind 的文件描述符变为监听套接字返回的情况和 bind 一样。 2.4 accept 函数
int accept(int sockfd, struct sockaddr *addr,int *addrlen); 服务器使用此函数获得连接请求并且建立连接。 ⚫ sockfd 是 listen 后的文件描述符。 ⚫ addr addrlen 是用来给客户端的程序填写的 , 服务器端只要传递指针就可以了 bind,listen 和 accept 是服务器端用的函数。 ⚫ accept 调用时服务器端的程序会一直阻塞到有一个客户程序发出了连接。 accept 成功时返回最后的服务器端的文件描述符这个时候服务器端可以向该描述符写信息了失败时返回-1 。 2.5 connect 函数
int connect(int sockfd, struct sockaddr * serv_addr,int addrlen); 可以用 connect 建立一个连接在 connect 中所指定的地址是想与之通信的服务器的地址。 ⚫ sockfd 是 socket 函数返回的文件描述符。 ⚫ serv_addr 储存了服务器端的连接信息其中 sin_add 是服务端的地址。 ⚫ addrlen 是 serv_addr 的长度 ⚫ connect 函数是客户端用来同服务端连接的 . 成功时返回 0 sockfd 是同服务端通讯的文件描述符失败时返回-1 。 2.6 send 函数
ssize_t send(int sockfd, const void *buf, size_t len, int flags); ⚫ sockfd 指定发送端套接字描述符 ⚫ buf 指明一个存放应用程序要发送数据的缓冲区 ⚫ len 指明实际要发送的数据的字节数 ⚫ flags 一般置 0 。 ⚫ 客户或者服务器应用程序都用 send 函数来向 TCP 连接的另一端发送数据 2.7 recv 函数
ssize_t recv(int sockfd, void *buf, size_t len, int flags); ⚫ sockfd 指定接收端套接字描述符 ⚫ buf 指明一个缓冲区该缓冲区用来存放 recv 函数接收到的数据 ⚫ len 指明 buf 的长度 ⚫ flags 一般置 0 。 ⚫ 客户或者服务器应用程序都用 recv 函数从 TCP 连接的另一端接收数据。 2.8 recvfrom 函数
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); ⚫ recvfrom 通常用于无连接套接字因为此函数可以获得发送者的地址。 ⚫ src_addr 是一个 struct sockaddr 类型的变量该变量保存源机的 IP 地址及端口号。 ⚫ addrlen 常置为 sizeof struct sockaddr 。 2.9 sendto 函数
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); ⚫ sendto 和 send 相似区别在于 sendto 允许在无连接的套接字上指定一个目标地址。 ⚫ dest_addr 表示目地机的 IP 地址和端口号信息。 ⚫ addrlen 常常被赋值为 sizeof struct sockaddr 。 ⚫ sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回 -1 。