• 网络编程基础+UDP的实现


    网络地址分类(32位网络地址)

    A类地址:第一个字节为网络地址,其他3个字节主机地址,第一字节的最高位固定为0

    1.0.0.1------126.255.255.255

    B类地址:第一字节和第二字节为网络地址,其他2个字节为主机地址,第一字节前两位固定为10

    128.0.0.1---191.255.255.255

    C类地址:前三个字节为网络地址,最后一个字节是主机地址,第一字节的前三位固定为110

    192.0.0.1----223.255.255.255

    D类地址:组播地址

    不分网络地址和主机地址,第一字节的前四位固定为1110

    224.0.0.1-----239.255.255.255

    注意几点:

    1192.168.1.255为广播地址,任何主机都是不能使用的。

    2、每一个网络地址都能组成一个小型的局域网。

    3127.0.0.1测试tcp,udp网络时使用的内部回环网络

    几种常见的网络分包格式

    一、 tcp数据包格式:

     

    Ethernet header:网络物理接口层(存放了网卡的MAC地址,共48位)

    Ip header:网络层,存放了目标主机的ip地址,源主机的ip地址

    TCP:传输层,存放了目标主机的port号和源主机的port号。这层确定传输是否可靠

    Ethernet trailer:对传输的数据进行CRC校验

    发送过程:应用层—>加个应用层头-à加个tcp---》加个ip---》加个ethernet (指定mac地址)---》最后对数据进行CRC校验。

    接收过程:反方向砍掉各种各样的头,先进行CRC校验---》验证MAC地址,如果匹配,则将其砍掉---》验证主机ip地址、匹配,将其砍掉----》验证tcpport,匹配将其砍掉---》最后只剩下数据了。

    Accept的第二个参数填放了目标主机的ip和端口号。

    二、 udp数据包格式:

     

    tcp差不多,只是传输层的协议改成了udp,面向不链接。

    Sendto的倒数第二个参数填放了目标主机的ip及端口等信息

    几种常见的网络分包格式

    三、 广播udp数据包格式:

     

    udp数据包有两个地方的区别:

    1、 分别是mac地址为FF :FF: FF: FF:FF:FF整个四十八位全为1

    2、 在网络层目标ip地址为:192.168.1.255

     

    四、 组播udp数据包格式:

     

    与广播udp数据包格式的区别主要在mac:组播数据包的mac目标地址为:[0 00500]前面为高25位,低23位为目标ip的低23位,这样的话,只要目标ip没有加入到组播,mac地址首先就无法匹配,这样大大提高了数据的传输效率,不用每次都需要匹配到udp 的传输层才能判断出是否要发送数据。

    UDP的通信的范例
    编程步骤:
    服务器(收数据):
    1、创建socket(socket())得到socketfd
    2、绑定本机ip(bind())一般绑定宏ip
    3、先接受数据得到对方的ip和port(recvfrom())
    4、发送数据(sendto())
    5、关闭socketfd(close())
    
    (发送数据)
    1、创建socket(socket())得到socketfd
    2、初始化对方主机的ip和端口号
    3、发送数据(sendto)倒数第二参数为对方的ip和port号
    4、接受数据
    5、关闭socket(close())
    
    
    服务器:
    #include<stdio.h>
    #include<netinet/in.h>
    #include<stdlib.h>
    #include<string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include<pthread.h>
    #include<strings.h>
    
    int main()
    {    int socketfd = socket(AF_INET,SOCK_DGRAM,0);//、、、、1.创建udp套接字socket得到socketfd
        struct sockaddr_in saddr;
        memset(&saddr,0,sizeof(saddr));
        saddr.sin_family = AF_INET;
        saddr.sin_port = htons(6000);
    //此处可以使用宏ip(=htonl(INADDR_ANY))该宏ip为一个整型数z转化为二进制L==long
        saddr.sin_addr.s_addr = inet_addr("192.168.193.2");
        if(bind(socketfd,(struct sockaddr*)&saddr,sizeof(struct sockaddr_in))<0)//2、、、、、、绑定本机的ip地址
            perror("bind() error!
    ");
        
        struct sockaddr_in caddr;
        int s = sizeof(struct sockaddr);    
        char buf[20],buf1[20];
        int n;
        while(1)//、、、、、、、、、、、、、、、、、、、、、、、、3.收发数据
        {    
            bzero(buf,20);
            //scanf("%s",buf);    
            if(n = recvfrom(socketfd,buf,20,0,(struct sockaddr *)&caddr,&s)<0)//recvfrom的倒数第二个参数为对方的ip和端口号,recvfrom函数自动获取,因此sendto中的地址就填该结构体。
                perror("send() error!
    ");
                printf("%s",buf);
                fgets(buf1,20,stdin);
            sendto(socketfd,buf1,strlen(buf),0,(struct sockaddr *)&caddr,s);
        }    
        close(socketfd);//、、、、、、、、、、4.关闭套接字socketfd
    
    }
    客户端:
    #include<stdio.h>
    #include<netinet/in.h>
    #include<stdlib.h>
    #include<string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include<pthread.h>
    #include<strings.h>
    
    int main()
    {    
    int socketfd = socket(AF_INET,SOCK_DGRAM,0);//、、、、、、、1.创建udp套接字得到socketfd文件描述符
        struct sockaddr_in saddr;
        memset(&saddr,0,sizeof(saddr));
        saddr.sin_family = AF_INET;
        saddr.sin_port = htons(6000);
        saddr.sin_addr.s_addr = inet_addr("192.168.193.2");//、、、2.初始化结构体sockaddr_in 目标主机的ip,sendto的倒数第二个参数
    
        
        struct sockaddr_in caddr;
        int s = sizeof(struct sockaddr);    
        char buf[20],buf1[20];
        int n;
        while(1)//、、、、3.发送接收数据.
        {    
            //bzero(buf,20);    
            fgets(buf,20,stdin);
            if(n = sendto(socketfd,buf,strlen(buf),0,(struct sockaddr *)&saddr,s)<0)
                perror("recv() error!
    ");
            //    printf("%d
    ",n);
            bzero(buf1,20);
            recvfrom(socketfd,buf1,20,0,(struct sockaddr *)&caddr,&s);
            printf("%s",buf1);
        }    
        close(socketfd);//、、、4.关闭socketfd
    
    }
  • 相关阅读:
    jQuery的几个Grid插件简单比较
    位运算符
    Unity --- 纹理压缩基本知识点
    Unity---资源管理中不同资源的路径获取方式
    Unity--- 资源路径问题
    数据结构 --- 基本概念
    《UnityShader入门精要》学习笔记之渲染流水线
    UnityShader中的语义相关
    补充一下角度制与弧度制的相关知识
    NGUI中处理层级问题的几个方法总结
  • 原文地址:https://www.cnblogs.com/defen/p/5287626.html
Copyright © 2020-2023  润新知