Socket

    xiaoxiao2021-03-25  78

    Linux的网络Socket()接口Socket

    socket种类: (SOCK_STREAM)

    式的可以提供可的、面向连使用TCP协议TCP证了数据传输

    数据报(SOCK_DGRAM)数据报字定义了无连服务数据通过相报文进行传输是无序的,并不保无差错,使用数据报协议UDP

    原始套

    原始套允许对层协议IPICMP访问主要的网络协议测试

    地址结

    struct sockaddr

    { u_short sa_family;

    char sa_data[14];

    } Sa_family:地址族AF_xxx式,:AF_INETSa_data:14特定协议地址

    地址结

    struct sockaddr_in{

    shortintsin_family; /*Internet地址族*/

    unsignedshortintsin_port; /**/

    struct in_addr sin_addr; /* IP地址*/

    unsignedcharsin_zero[8]; /*0*/

    }并不sockaddr数据结而是使用sockaddrsockaddr_in

    struct in_addr{

    unsigned long s_addr;

    }

    S_addr: 32位的地址

    地址

    IP地址通字加(192.168.0.1)表示struct in_addr使用的IP地址是由32位的数表示的,了转我们可以使用:

    int inet_aton(const char *cp,struct in_addr *inp)

    char *inet_ntoa(struct in_addr in)

    aascii nnetwork.第一数表示a.b.c.d式的IP换为32位的IP,存储inp指针里面。32IP换为a.b.c.d式。

    CPU 变量 存储顺 :有的 系统 是高 位在 位在 有的 系统 位在 位在 网络 传输 数据 的。所 存储顺 网络 序不 进行

    32bit(0x01234567)地址0x100开始: 

    网络TCP/IP中规定好数据表示式,与具CPU系统无关,从可以数据在不同主机之间传输。网络big endian式。

    htonsunsigned short主机网络序

    htonlunsigned long主机网络序

    ntohsunsigned short从网络序主机

    ntohlunsigned long从网络序主机

    IP主机名

    在网络上可以IP可以使用主机名

    struct hostent *gethostbyname(const char *hostname)

    struct hostent{

    char *h_name;/* 主机名称 */

    char *h_aliases;/* 主机名 */

    int h_addrtype;/* 主机地址型 AF_INET*/

    int h_length;/* 主机地址度 */

    char **h_addr_list;/* 主机IP地址表 */

    }

    #defineh_addrh_addr_list[0] /*主机第一IP地址*/

    地址

    IP地址通字加(192.168.0.1)表示struct in_addr使用的IP地址是由32位的数表示的,了转我们可以使用:

    int inet_aton(const char *cp,struct in_addr *inp) 

    char *inet_ntoa(struct in_addr in)

    aascii nnetwork.第一数表示a.b.c.d式的IP换为32位的IP,存储inp指针里

    面。32IP换为a.b.c.d式。

    进行Socket程的有:

    socket

    socket

    bind

    绑定IP地址和socket

    connect

    绑定client服务器建立连

    listen

    处理接要Listen()并未开始收连线只是socketlisten式。 accept 用来socket

    send

    送数据

    recv

    数据

    TCP-服务

    1.socket,用socket()

    绑定IP地址口等信息socket上,用bind()

    允许接数,用listen()

    上来的,用accept()

    收发数据,用send()recv(),或者read()write()

    关闭网络

    TCP-

    1.socket,用socket()

    IP地址和口等属性

    接服务,用connect()

    收发数据,用send()recv(),或者read()write()

    关闭网络接 

    基于UDP-服务器 

    创建一个socket,用函数socket()  绑定IP地址、端口等信息到socket上, 用函数bind()  循环接收数据,用函数recvfrom()  关闭网络连接

    基于UDP-客户端 

    创建一个socket,用函数socket()  绑定IP地址、端口等信息到socket上, 用函数bind()  设置对方的IP地址和端口等属性  发送数据,用函数sendto()  关闭网络连接

    服务器模型 

    在网络程序里面,一般来说都是许多客户对应一 个服务器,为了处理客户的请求, 对服务端的程 序就提出了特殊的要求。目前最常用的服务器模 型有: • 循环服务器:服务器在同一个时刻只可以响应 一个客户端的请求并发服务器:服务器在同一个时刻可以响应多 个客户端的请求 

    UDP循环服务器 

    UDP循环服务器的实现方法:UDP服务器每次从套接字上读取一 个客户端的请求->处理->然后将结果返回给客户机。

    socket(...); 

    bind(...); 

    while(1) 

    { recvfrom(...); 

    process(...);

    sendto(...); 

    因为UDP是非面向连接的,没有一个客户端可以老是占住服务 端, 服务器对于每一个客户机的请求总是能够满足。 

    TCP循环服务器

     TCP服务器接受一个客户端的连接,然后处理,完成了这个客户的所有请求后,断开连接。算法如下

    socket(...); 

    bind(...); 

    listen(...); 

    while(1) 

    { accept(...); 

    process(...);

    close(...); 

    TCP循环服务器一次只能处理一个客户端的请 求。只有在这个客户的所有请求都满足后, 服务 器才可以继续后面的请求。这样如果有一个客户 端占住服务器不放时,其它的客户机都不能工作 了,因此,TCP服务器一般很少用循环服务器模 型的。 

              

    TCP并发服务器 

    并发服务器的思想是每一个客户机的请求并不由服务器直接处理,而是由服务器创建一个 子进程来处理。算法如下

    socket(...); 

    bind(...);

     listen(...);

     while(1) 

    accept(...);

    if(fork(..)==0) 

    process(...); 

    close(...); 

    exit(...); 

    close(...); 

    TCP并发服务器 TCP并发服务器可以解决TCP循环服 务器客户机独占服务器的情况。但同时也带来了问题:为了响应客户的请求,服务器要创建子进程来处理,而创 建子进程是一种非常消耗资源的操作。 

    多路复用I/O 

    阻塞函数在完成其指定的任务以前不允许程序继续向下 执行。例如:当服务器运行到accept语句时,而没有客 户请求连接,服务器就会停止在accept语句上等待连接 请求的到来。这种情况称为阻塞(blocking),而非阻 塞操作则可以立即完成。例如,如果你希望服务器仅仅 检查是否有客户在等待连接,有就接受连接,否则就继 续做其他事情,则可以通过使用select系统调用来实 现。除此之外,select还可以同时监视多个套接字  

                

    多路复用I/O int select(int maxfd, fd_set *readfds, fd_set *writefds, fe_set *exceptfds, const struct timeval *timeout) 

     Maxfd: 文件描述符的范围,比待检的最大文件描述符大 Readfds:被读监控的文件描述符集  Writefds:被写监控的文件描述符集  Exceptfds:被异常监控的文件描述符集  Timeout:定时器

    多路复用I/O Timeout取不同的值,该调用有不同的表现

    Timeout值为0,不管是否有文件满足要求,都立刻返 回,无文件满足要求返回0,有文件满足要求返回一个正值。 

    TimeoutNULLselect将阻塞进程,直到某个文件满足要求 

    Timeout值为正整数,就是等待的最长时间,即 selecttimeout时间内阻塞进程。 

    多路复用I/O 

    Select调用返回时,返回值有如下情况

    1. 正常情况下返回满足要求的文件描述符个数; 

    2.经过了timeout等待后仍无文件满足要求,返 回值为0; 

    3. 如果select被某个信号中断,它将返回-1并设 errnoEINTR 

    4. 如果出错,返回-1并设置相应的errno 

                

    多路复用I/O

    1. 设置要监控的文件 

    2. 调用Select开始监控 

    3. 判断文件是否发生变化 

       

    多路复用I/O 

    系统提供了4个宏对描述符集进行操作: #

    include <sys/select.h> void FD_SET(int fd, fd_set *fdset) 

    void FD_CLR(int fd, fd_set *fdset)

    void FD_ZERO(fd_set *fdset) 

    void FD_ISSET(int fd, fd_set *fdset) 

    FD_SET将文件描述符fd添加到文件描述符集fdset中; 

    FD_CLR从文件描述符集fdset中清除文件描述符fd;

     FD_ZERO清空文件描述符集fdset; 

    在调用select后使用FD_ISSET来检测文件描述符集fdset中的文件fd发生了变化。 

             

    多路复用I/O 

    FD_ZERO(&fds); //清空集合 sock1 = socket(......); sock2 = socket(......); bind(sock1,...); bind(sock2,...); listen(sock1,...); listen(sock1,...); FD_SET(sock1,&fds); //设置描述符 FD_SET(sock2,&fds); //设置描述符 maxfdp=(sock1>sock2?sock1:sock2) + 1; 

    switch(select(maxfdp,&fds,NULL,NULL,&timeout)) case -1: exit(-1);break; //select错误,退出程序 case 0:break; default: 

    if(FD_ISSET(sock1,&fds)) //测试sock1是否可读 accpet(sock1,...) 

    转载请注明原文地址: https://ju.6miu.com/read-34231.html

    最新回复(0)