网络-程序流程

域名解析顺序

  1. etc/hosts或Windows的hosts

  2. etc/resolv.conf中查找域名服务器(DHCP可以自动分配域名服务器)

  3. DNS服务器查找IP

gethostbyname() //return struct hostent

   struct hostent  
   {  
   char *h_name;                 /*official name of host*/    
   char **h_aliases;             /*alias list*/    
   int h_addrtype;                /*host address type*/  
   int h_length;                    /*length of address*/  
   char **h_addr_list;          /*list of addresses*/  
   } 

TCP/IP协议族

 1.分层的概念(五层概念模型)  
     应用层:HTTP(Hypertext Transfer Protocol),FTP(File Transfer Protocol),SMTP(Simple Mail Transfer Protocol),SSH(22),TELNET(23)  
     传输层:解决进程接受数据  TCP(Transmission Control Protocol),UDP (User Datagram protocol)
     网络层:解决网络传输问题  IP(Internet Protocol),ICMP(Internet Control Message Protocol),ARP(Address Resolution Protocol),RARP(Reverse ARP),
     LLC层(MAC):解决局域网链路问题  (典型协议ARP)    
     物理层:PCS(物理编码层)PMA(物理适配层)  
常用协议
数据链路层是负责接收IP数据包并通过网络发送,或者从网络上接收物理帧,  
抽出IP数据包,交给IP层。  

ARP是正向地址解析协议,通过已知的IP,寻找对应主机的MAC地址。  

RARP是反向地址解析协议,通过MAC地址确定IP地址。比如无盘工作站还有DHCP服务。  

ICMP是网络层的补充,可以回送报文。用来检测网络是否通畅。  

Ping命令就是发送ICMP的echo包,通过回送的echo relay进行网络测试。  

IP地址转换(本地-网络)

    点分十进制(char*)————二进制(int)

    本地字节序(小端序)————网络字节序(大端序)  
case1:点分十进制————>网络字节序的二进制
    in_addr_t inet_addr(const char* cp)  

    int inet_aton(const char* cp,struct in_addr* inp) 
case2:网络字节序的二进制————>点分十进制
    char* inet_ntoa(struct in_addr in)  

其他转换函数

htons------host to net short

htonl------host to net long

ntohs------net to host short

ntohl------net to host long

子网掩码

     24——表示前24位为1后八位为0  

     255.255.255.0——表示前24位为1后八位为0

作用:将ip地址扩大到ip地址段

HTTP协议(解包)

  1. 数据包第一步到网卡
  2. 链路层解包)网卡驱动————MAC包头
  3. (tcp/ip层解包)内核协议栈————IP/TCP包头

tcp编程

监听句柄————>接收新的链接

链接句柄————>接收新的客户端—accept()阻塞

 read()/write() 

 recvmsg()/sendmsg()   
1.create socket创建流式套接字
     用法:int sock=socket(协议族,套接字类型,传输协议)  

函数原型:int socket(int protofamily,int type,int protocol);//返回socket fd

  • 例:ICMP

socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);

  • 例:SYN

socket(AF_INET,SOCK_RAW,IPPROTO_IP);

   协议族:AF_INET AF_INET6 AF_LOCAL AF_ROUTE  

   套接字类型:SOCK_STREAM SOCK_DGRAM SOCK_RAM  

   传输协议:IPPROTO_TCP IPPROTO_UDP IPPROTO_SCTP IPPROTO_TIPC  
2.用struct sockaddr_in结构体来封装信息

结构体原型:

struct sockaddr_in

{

sin_family;//协议族

sin_port;//端口号(网络字节序二进制)

sin_addr.s_addr;IP地址(网络字节序二进制)

}

源地址赋值
bzero(&connection._addr,sizeof(connection._addr));
connection._addr.sin_family = AF_INET;
通常TCP/UDP 协议源地址和端口都是随机的
INADDR_ANY&0转不转网络字节序无所谓
connection._addr.sin_addr.s_addr = htons(INADDR_ANY);
connection._addr.sin_port = htons(0);
目的地址赋值
bzero(&connection.server_addr,sizeof(connection.server_addr));
connection.server_addr.sin_family = AF_INET;
connection.server_addr.sin_addr.s_addr=inet_addr(server_ip); —inet_addr()的缺陷:必须对-1做检测处理
因为inet_addr()的结果是整型,而发生错误时返回-1。
而 ina.sin_addr.s_addr是unsigned long型
-1在long short显示成111111111,和IP地址255.255.255.255相符合!会被误认为广播地址!
connection.servaddr.sin_port = htons(server_port); —若server_port为char*类型 使用atoi()转换

3.将信息绑定到套接字上bind()
     用法:bind(套接字句柄,强转为struct sockaddr*类型的地址,信息的大小);——返回值小于0-失败  

函数原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

4.打开监听句柄接收链接信息listen()
     listen(套接字句柄,链接个数);——返回值小于0-失败  

函数原型:int listen(int sockfd, int backlog);

5.打开连接句柄接收客户端accept()

函数原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);—— 返回连接connect_fd

TCP源码

struct tcphdr {
    __be16    source;
    __be16    dest;
    __be32    seq;
    __be32    ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u16    res1:4,
        doff:4,
        fin:1,
        syn:1,
        rst:1,
        psh:1,
        ack:1,
        urg:1,
        ece:1,
        cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
    __u16    doff:4,
        res1:4,
        cwr:1,
        ece:1,
        urg:1,
        ack:1,
        psh:1,
        rst:1,
        syn:1,
        fin:1;
#else
#error    "Adjust your <asm/byteorder.h> defines"
#endif    
    __be16    window;
    __sum16    check;
    __be16    urg_ptr;
};

IP源码

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8    ihl:4,
        version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
    __u8    version:4,
          ihl:4;
#else
#error    "Please fix <asm/byteorder.h>"
#endif
    __u8    tos;
    __be16    tot_len;
    __be16    id;
    __be16    frag_off;
    __u8    ttl;
    __u8    protocol;
    __sum16    check;
    __be32    saddr;
    __be32    daddr;
    /*The options start here. */
};

UDP编程

recvfrom()/sendto()

广播数据包(广播只在局域网中,不能跨网段)
 路由器不会转发广播数据包  

 交换机会转发广播数据包

 广播包的目的地址(mac)为FF:FF:FF:FF:FF:FF
组播数据包(在组播组中进行传播)
 路由器可以转发组播数据包
socket选项设置与读取函数
 int getsockopt(int sockfd,int level,int optname,void* optval,socklen_t *optlen);  

 int setsockopt(int sockfd,int level,int optname,const void* optval,socklen_t *optlen);      
udp_group_broadcast_recv
  1. 创建和绑定UDP

  2. 将当前UDP加入到组播组中

  3. recvfrom()接收到组播组其他成员的消息

udp_group_broadcast_send
  1. 创建和绑定UDP

  2. sendto()发送消息到组播组其他成员(需要传入当前的地址peeraddr)

组播结构体

    struct ip_mreq  
    {  
    struct in_addr imr_multiaddr;/*multicast group to join*/  
    struct in_addr imr_interface;/*interface to join one*/  
    } 

    //多播组的IP地址  
    //加入的客户端主机IP地址

相关函数原型

    ssize_t read(int fd, void *buf, size_t count);  
    ssize_t write(int fd, const void *buf, size_t count);

    ssize_t send(int sockfd, const void *buf, size_t len, int flags);  
    ssize_t recv(int sockfd, void *buf, size_t len, int flags);

    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,  
        	const struct sockaddr *dest_addr, socklen_t addrlen);  

    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值