您的位置:首页 > 理论基础 > 计算机网络

Tcp通信

2013-12-28 23:43 204 查看
1、TCP通信过程

socket在Tcp/IP分层的哪里?



socket是应用层与Tcp/IP协议族通信中间软件抽象层,是一组接口。在设计模式中,其实就是一个门面模式,他把复杂的协议族隐藏在接口后面,对用户来说,一组简单的接口就是全部,让socket去组织数据,以符合指定的协议。

一个典型的通信过程如下图所示



工作过程:服务器端首先启动,通过调用socket函数创建一个套接字;然后调用bind函数将该套接字与一个本地地址和端口绑定在一起;接着调用listen函数将套接字设置为监听模式,准备接受用户请求;调用accept函数接收连接:等待用户请求的到来,当来时接收连接请求,返回一个新的对应于此的连接套接字;用返回的套接字和客户端进行通信,使用函数send/recv;返回,等待另一个请求的到来;最后关闭套接字。

客户端:使用socket函数创建一个套接字;使用函数connect向服务器发送连接请求;之后就可以和服务器进行通信,使用函数send/recv。

相关函数讲解:

(1)int socket(int family, int type, int protocol);

family(协议族):AF_INET:IPv4协议

AF_INET6:IPv6协议

AF_LOCAL:UNIX域协议

AF_ROUTE:路由套接字

AF_KEY:秘钥套接字

type(套接字类型):SOCK_STREAM:字节流套接字;SOCK_DGRAM:数据报套接字;SOCK_RAW:原始套接字

protocl:0原始套接字除外

返回值:成功,非负套接字描述符;出错-1

返回-1时,errno值将设为下列这些值:

EPROTONOSUPPORT:错误原因是参数中的错误,表示申请的服务或指定的协议无效;
EMFILE:错误的原因是应用程序的描述符已满;
ENFILE:错误的原因是应用程序内部的系统文件表已满;
ENOBUF:错误的原因是系统没有可用的缓冲空间

(2)绑定本地地址

int bind(int socktd, struct sockadddr *my_addr, int addrlen)

socktd: 套接字描述符;my_addr:本地地址;addrlen:地址长度

成功0,出错-1

(3)listen函数

int listen(int socktd,int backlog)

socktd:套接字描述符;backlog:请求对列中允许的最大请求数,表示在accept函数之前同时最多有多少个客户连接到这个套接字

成功0,失败-1

listen函数将一个套接字转换成监听套接字,主要做下面两件事:

socket函数建立的套接字是一个未连接的套接字,这是还不能接收内核向此套接字提供的连接请求,调用listen函数后,将这个套接字有CLOSE状态转为LISTEN状态,这时才可以准备接收内核发出的连接请求信号

由于可能会同时有很多连接请求需要处理,listen函数可以确定连接请求对列的长度。

(4)accept函数

int accept(int socktd, struct sockaddr *addr, socklen_t *addrlen)

socktd:套接字描述符;addr:客户端地址;addrlen:地址长度

函数返回值是一个套接字,程序可以用这个套接字和客户端进行通信。

(5)客户端和服务器建立连接后,可以通过函数read和write完成数据通信,但对于socket通信来说,可以用send和recv系统调用更好的进行套接字操作

int send (int socktd, const void *msg,int len, int flags)

socktd:套接字描述符,msg:指向要发送数据的指针,len:数据长度,flags一般为0;成功返回发送的字节数,否则0

int recv(int socktd, void *buf,int len, unsign int flags)

socktd:套接字描述符,buf:存放接收数据的缓冲区,len:数据的长度,flas:一般0

成功返回接收的字节数,否则0

(6)int connect(int socktd,const struct sockaddr*server_addr, socklen_t addrlen)

函数的功能是完成一个有连接协议的连接过程,对于TC P 来说就是那个三次握手过程。在建立连接的时候,总会有一方先发送数据,谁调用了connect谁就先发送数据。因此必须制定数据的发送地址,同时必须指定数据从哪里发送,这正好是前两个参数。

socktd: 套接口描述符,解决从哪里发送的问题。内核需要维护大量的IO通道,所以用户必须通过这个参数告诉内核从哪个IO通道,此处是从哪个socket接口发送数据。;

server_addr: 目标地址指针,包含IP和端口信息,也就是服务器端的地址,被连接的一方需要调用listen接收connect的连接请求,如此被动连接的一方就是服务器了;

addrlen:地址长度
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: