Socket

Linux的网络Socket()接口Socket

socket种类:
(SOCK_STREAM)

page431image2080

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

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

原始套

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

地址结

struct sockaddr

page433image2128

{
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*/

page434image3080

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

struct in_addr{

unsigned long s_addr;

}

S_addr: 32位的地址

地址

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

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变量存储顺:有的系统是高位在位在有的系统位在位在网络传输数据的。所存储顺网络序不进行page437image1632
page438image1664

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


page439image1640

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

htonsunsigned short主机网络序page441image1632page440image1888

htonlunsigned long主机网络序

ntohsunsigned short从网络序主机

ntohlunsigned long从网络序主机


IP主机名

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

page442image1800

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地址*/



地址

page443image1632

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

page444image2952

绑定client服务器建立连

page445image2192

listen

page445image2800page445image2968page445image3136page445image3304page445image3472page445image3640page445image3808page445image3976page445image4144page445image4312page445image4480page445image4648page445image4816page445image4984page445image5152page445image5320page445image5488page445image5656

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

send

送数据

recv

数据

TCP-服务

1.socket,用socket()

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

  2. 允许接数,用listen()

  3. 上来的,用accept()

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

  5. 关闭网络

TCP-

1.socket,用socket()

  1. IP地址和口等属性

  2. 接服务,用connect()

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

  4. 关闭网络接 


    基于UDP-服务器 

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

    基于UDP-客户端 

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



    服务器模型 

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


    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,...) 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值