第四章 基于TCP的服务器端/客户端(1)

来源:互联网 发布:iphone自动读书软件 编辑:程序博客网 时间:2024/06/10 20:33

《TCP/IP网络编程》 尹圣雨

P59~P71


1.理解TCP和UDP

根据数据传输方式不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字。TCP套接字是面向连接的,称为基于流的套接字。


  

各层通过操作系统等软件实现,也可能通过类型NIC的硬件设备实现。

 

补充:开放式系统 Opening System(以多个标准为依据设计的系统)

路由器用来完成IP层交互任务。网卡遵守链路层的协议标准。

 

(1)链路层:是物理链接领域标准化的结果,也是最基本的领域,专门定义LAN、WAN、MAN等网络标准。

(2)IP层:在复杂网络中传输数据,需要考虑路径的选择。即向目标传输数据需要经过哪条路径?

IP本身是面向消息、不可靠的协议。每次传输数据时会帮助选择路径,但并不一致。IP协议无法应对数据错误。

(3)TCP/UDP层:TCP/UDP层以IP层提供的路径信息为基础完成实际的数据传输,也称为传输层Transport。TCP可以保证可靠的数据传输。但它发送数据是以IP层为基础。

IP层只关注1个数据包(数据传输的基本单位)的传输过程。

TCP作用:交换过程中可以确认对方已经收到数据,并重传丢失的数据,即使IP层不保证数据传输,此类通信也是可靠的。TCP协议确认后向不可靠的IP协议赋予可靠性

(4)应用层:编写软件过程中,需要根据程序特点决定服务器端和客户端间的数据传输规则,即是应用层协议。

 

2 实现基于TCP的服务器端/客户端

服务器端的默认函数调用顺序:

socket()→bind()→listen()→accept()→read()/write()→close()

 

进入等待连接请求状态

#include<sys/socket.h>

int listen(int sock, intbacklog);

成功时返回0,失败时返回-1。

Sock:希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数成为服务器端套接字(监听套接字)。

Backlog:连接请求等待队列长度

 

受理客户端请求状态

#include<sys/socket.h>

int accept(int sock,structsockaddr *addr,socklen_t addrlen);

成功时返回创建的套接字文件描述符,失败时返回-1.

sock:服务器套接字的文件描述符。

addr:保存发起连接请求的客户端地址信息的变量地址值,调用函数后向传递来的地址变量参数填充客户端地址信息。

addrlen:第二个参数addr结构体的长度,但是存有长度的变量地址。函数调用完成后,该变量即被填入客户端地址长度。

 

函数调用成功时,accept函数内部将产生用于数据I/O的套接字,并返回其文件描述符。需要强调的是,套接字是自动创建的,并自动与发起连接请求的客户端建立连接。

 

TCP客户端的默认函数调用顺序

socket()→connect()→read()/write()→close()

#include<sys/socket.h>

int connect(int sock, structsockaddr * servaddr,socklen_t addrlen);//成功时返回0,失败时返回-1

sock:客户端套接字文件描述符

servaddr:保存目标服务器端地址的变量地址值

addrlen:以字节为单位传递已传递给第二个结构体参数servaddr的地址变量长度。

 

客户端调用connect函数后,发生以下情况会返回(完成函数调用)。

1)   服务器端接收连接请求

2)   发生断网等异常情况而中断连接请求

注意:“接收请求”是指服务器端把连接请求信息记录到等待队列,因此connect函数返回后并不立即进行数据交换。

 

客户端套接字何时、何地、如何分配地址?

调用connect函数时;在操作系统(内核中);IP用计算机(主机)的IP,端口随机。

 

基于TCP的服务器端/客户端函数调用关系

服务器端创建套接字后连续调用bind、listen函数进入等待状态,客户端通过调用connect函数发起连接请求。客户端只能等到服务器端调用listen函数后才能调用connect函数。同时要清楚,客户端调用connect函数前,服务器端可能率先调用accept函数。此时服务器端在调用accept函数时进入阻塞状态,直到客户端调用connect函数为止。

 

 

阅读全文
0 0
原创粉丝点击