Chinaunix首页 | 论坛 | 博客
  • 博客访问: 70171
  • 博文数量: 24
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 245
  • 用 户 组: 普通用户
  • 注册时间: 2014-12-10 08:06
文章分类
文章存档

2015年(24)

我的朋友

分类: 嵌入式

2015-04-28 23:09:53

网络中进程的通信方式:
网络间的进程几乎全都是通过socket进行通信的。
本地间的进程通讯方式可以分为:
    (1)消息传递:管道、FIFO、消息队列
     (2)同步:互斥量、条件变量、读写锁、信号量
     (3)内存共享
     (4)远程过程调用
本地进程可以用PID唯一标识。如何标识网络间的进程呢?TCP/IP协议族已经很好的解决了这个问题,“网络层的IP”标志一台主机的位置,“协议+端口号”标识一台主机中的进程。那么“IP、协议、端口号”这个三元组就可以清楚的标识网络中的一个进程。
什么是socket
socket起源于UNIX,UNIX/linux的一个基本理念为:一切接文件。都可以用“open——>read/write——>close”进行操作,因此socket也是一种特殊的文件,也适用于open——>read/write——>close”模型。
socket函数
int socket(int domain, int type, int protocol)
函数的作用:用于创建一个socket
返回:套接字文件描述符
domain:协议域,又称为协议族(family)。常用的协议族有:AF_INET、AF_INET6、AF_LOCAL(或者AF_UNIX, unix中的socket协议族)、AF_ROUTE。domain就决定了socket的地址类型,AF_INET表明IP使用IPV4类型,端口为16位。

type:指明套接字的类型。套接字可以分为:SOCK_STREAM、SOCK_DGRAM、SOCK_RAW。
protocol:指明所用协议。IPPROTO_TCP、IPPROTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC。分别对应TCP协议、UDP协议、STCP协议、TIPC协议。
type与protocol不可以随意组合,当protocol为0时,系统会自动寻找与type匹配的protocol。
bind()函数         
int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen)
函数的作用:将地址和端口号赋给创建的socket。

sockfd: 套结字描述符,唯一的标识一个socket,bind就是将这个描述符绑定一个名字。
addr:指向要绑定给sockfd的协议地址。
addrlen:对应的是地址的长度
通常服务器在启动时会绑定一个众所周知的地址(IP和端口号),用于提供服务;对于客户端,在调用connect函数时,系统会自动为其分配一个端口号,因此不需要调用该端口号与客户端的IP地址就组成了客户端的网络地址。

网络字节序和主机字节序
(1)主机字节序:字节序指的是大于一个字节的基本类型数据在内存中的存放格式,就是我们常说的大端(big-endian)与小端(little-endian)模式。对于单字节类型的数据,大端、小端是一样的,不同类型CPU的字节序有所不同,x86CPU采用小端模式;arm处理器一般为小端模式,有的既支持大端模式,又支持小端模式,可以通过软设置进行设置;powerpc采用的是大端模式。    
  1) little-endian, 低字节存放在低地址,高字节存放在高地址。
     2)big-enddian, 低字节存放在高地址,高字节存放在低地址。
(2)网络字节序,数据在网络中的存放格式是大端格式。
在将地址绑定给socket之前要先转换成网络字节序,以免因为主机字节序与网络字节序不同
而造成接收的数据出错。
listen函数
在调用了socket()、bind()函数之后,用listen()函数来监听socket,当客户端调用connect函数发送请求时,服务器端便会链接服务器。
   int listen(int sockfd, int backlog);
sockfd:套接字描述符
backlog:相应socket的可以排队的最大连接数
socket()创建的socket是一个主动类型,listen()将socket转变为被动类型,等待用户来连接。

connect 函数
int 
connect(int sockfd, struct sock_addr addr, socklen_t sockaddr_len);
sockfd: 套接字描述符
addr:服务器端的地址
sockaddr_len:服务器端地址的长度
connect函数用来连接
服务器accept函数服务器端依次调用了 socket、bind、listen函数之后,listen函数监听服务器端的socket;然后客户端调用socket函数,然后用connect信息请求连接;当服务器端监听到客户端的发来请求,然后调用accept函数来接收请求,进行连接。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addr_len)

sockfd:套接字描述符。
addr:客户端地址
addr_len:存储地址长度的地址变量
I/O操作  
在客户端与服务器端建立了连接之后,就可以进行网络I/O操作。常用的网络操作有:
   read()/write()   
  recv()/send()  
 readv()/writev()
  recvmsg()/sendmsg()
  recvfrom()/sendto()
这里向socket写入数据时,会为数据加上头和尾;另一端都数据时只有即读到头,又读到尾时才认为读到了完整的信息。否则读取的数据出错。

close函数
int close(int sockfd)

close函数只是使相应socket描述字的引用值减1,只有当引用值减为0时,才会引发客户端向服务器端发送终止请求.

socket中TCP三次握手建立连接
socket经历三次握手建立了服务器与客户端之间的链接,又称为三次分组,具体过程如下:
(1)客户端调用connect向服务器端发送 SYN J,之后connect就会处于阻塞状态,
(2)服务器监听到客户端的请求,即收到了SYN J包之后,调用accept函数,向客户端发送SYN K、SYN J+1,accept就会阻塞
(3)客户端接收到SYN K、SYN J+1之后,connect函数就会返回,并向服务器端发送SYN K+1进行确认,服务器端收到SYN K之后便          会返回
三次握手建立连接的示意图如下图:

 

SOCKET中四次握手释放连接 
(1)当客户端调close时,客户端向服务器端发送FIN M
(2)服务器端收到FIN M之后,执行被动关闭,然后向客户端发送FIN M+1进行确认。接收的FIN M作为文件结束符传递给应用程序,         即应用程序无法通过连接接收数据。
(3)一段时间之后,接收文件结束符的进程会调用close函数关闭它的socket,并先客户端发送FIN N
(4)客户端接收到之后,会发送FIN N+1进行确认。
 解除连接的四次握手示意图如下













































阅读(795) | 评论(0) | 转发(0) |
0

上一篇:HTML基础

下一篇:bash作业管理

给主人留下些什么吧!~~