socket编程

TCP连接的3次握手
屏幕快照 2017-04-18 下午10.13.14

  • 首先服务器端调用socket函数(返回一个套接字),然后套接字与地址、端口绑定(bind),然后对端口进行监听(listen),调用accept阻塞等待客户端的连接; 客户端调用socket函数(返回一个套接字),然后连接服务器(connect),如果连接成功,这时客户端与服务器端的建立就建立了

  • 客户端通过调用connect进行主动打开,这引起客户端向服务器放送一个 SYN seq=J 的请求,这时客户端的connect进入到阻塞状态,服务器端监听到连接请求,即收到SYN seq=J的分节,调用accept函数接受请求,并向客户端发送 SYN K ACK = J+1 的分节,此时accept进入阻塞状态,客户端收到服务器的SYN seq=K,ACK J+1的分节之后,connect开始返回,并对SYN K的分节进行确认,服务器收到ACK seq=K+1分节时,accept返回,至此3次握手完成。

    屏幕快照 2017-04-18 下午9.08.45

网络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭),这些函数我们在后面进行介绍.

  • socket函数

    int socket(int domain, int type, int protocol);
    

    socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建一个socket描述符(socket descriptor),它唯一标识一个socket。这个socket描述字跟文件描述字一样,后续的操作都有用到它,把它作为参数,通过它来进行一些读写操作。

    正如可以给fopen的传入不同参数值,以打开不同的文件。创建socket的时候,也可以指定不同的参数创建不同的socket描述符,socket函数的三个参数分别为:

    • domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
    • type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的类型有哪些?)。
    • protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
  • bind函数:把一个地址族中的特定地址赋给socket。例如对应AF_INET、AF_INET6就是把一个ipv4或ipv6地址和端口号组合赋给socket

    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    

    函数的三个参数分别为:

    • sockfd:即socket描述字,它是通过socket()函数创建了,唯一标识一个socket。bind()函数就是将给这个描述字绑定一个名字。
    • addr:一个const struct sockaddr *指针,指向要绑定给sockfd的协议地址。这个地址结构根据地址创建socket时的地址协议族的不同而不同。
      a

    • addrlen:对应的是地址的长度。

      通常服务器在启动的时候都会绑定一个众所周知的地址(如ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,有系统自动分配一个端口号和自身的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在connect()时由系统随机生成一个。

      a2

  • listen()、connect()函数
    屏幕快照 2017-04-18 下午10.02.51

  • accept()函数
    屏幕快照 2017-04-18 下午10.04.50

  • read()、write()等函数

eee

  • close()函数
    屏幕快照 2017-04-18 下午10.12.01

  • Socket中TCP的3次握手
    屏幕快照 2017-04-18 下午10.13.14

    屏幕快照 2017-04-18 下午10.13.54

  • socket中TCP的四次握手释放连接详解

    屏幕快照 2017-04-18 下午10.15.50

    屏幕快照 2017-04-18 下午10.15.59

posted @ 2017-04-20 15:31  I呆呆  阅读(247)  评论(0编辑  收藏  举报