zoukankan      html  css  js  c++  java
  • 重温网络编程——常识(三)

    前言

    关于一些网络编程的常识整理。

    正文

    1.网络数据传输到我们的计算机,是如何知道传输给那个应用?
    通过端口,所以端口也是不能重复占用的。
    2.
    下面是sockaddr_in 的定义:

    typedef struct sockaddr_in {
    
    #if(_WIN32_WINNT < 0x0600)
        short   sin_family;
    #else //(_WIN32_WINNT < 0x0600)
        ADDRESS_FAMILY sin_family;
    #endif //(_WIN32_WINNT < 0x0600)
    
        USHORT sin_port;
        IN_ADDR sin_addr;
        CHAR sin_zero[8];
    } SOCKADDR_IN, *PSOCKADDR_IN;
    

    1.sin_family 设置的为地址族
    2.sin_port 为端口号,16位也就是两个字节,所以端口范围是1-65535,其中1-1000是系统保留的端口号,但是并不是我们不能用,只是最后不用。
    1024-5000: BSD临时端口,一般的应用程序使用1024到4999来进行通讯;
    5001-65535: BSD服务器(非特权)端口,用来给用户自定义端口.
    3. ip 地址的定义

    typedef struct in_addr {
            union {
                    struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
                    struct { USHORT s_w1,s_w2; } S_un_w;
                    ULONG S_addr;
            } S_un;
    #define s_addr  S_un.S_addr /* can be used for most tcp & ip code */
    #define s_host  S_un.S_un_b.s_b2    // host on imp
    #define s_net   S_un.S_un_b.s_b1    // network
    #define s_imp   S_un.S_un_w.s_w2    // imp
    #define s_impno S_un.S_un_b.s_b4    // imp #
    #define s_lh    S_un.S_un_b.s_b3    // logical host
    } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
    
    1. sin_zero
      只是为了sock_addr_in 的大小与sockaddr 结构体保持一致插入的成员。
      下面是sockadrr 的声明:
    typedef struct sockaddr {
    
    #if (_WIN32_WINNT < 0x0600)
        u_short sa_family;
    #else
        ADDRESS_FAMILY sa_family;           // Address family.
    #endif //(_WIN32_WINNT < 0x0600)
    
        CHAR sa_data[14];                   // Up to 14 bytes of direct address.
    } SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
    
    

    只是因为CHAR sa_data[14];保存ip与端口过于麻烦,多出的部分补充为0,所以引用了sockaddr_in来人性化操作。

    5.cpu 向内存中保存数据的方式有两种。

    大端序:高位字节存放在低位地址。
    小端序:高位字节存放在高位地址。
    例如: int32 数字1,二进制 00000000 00000000 00000000 00000001
    这种就是大端序。
    然后小端序是:00000001 00000000 00000000 00000000
    因为我们传递的时候实际上传递的是信号,也就是二进制。
    如果大端号遇到小端号,他们接收的数据正确但是理解是不一样的。
    所以在传输数据的时候约定全部转换成大端序。
    所以有了下面几个函数:

    unsigned short htons(unsigned short);
    unsigned short ntohs(unsigned short);
    unsigned long htonl(unsigned long);
    unsigned long htonl(unsigned long);
    

    h:主机字节序
    t:to
    n:网络字节序
    s:short
    l:long
    之所以有long,因为long在linux 中为4个字节,可以用来转换ip
    htons 用来转换端口。
    所以传输地址为:

    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(atoi(argv[1]));
    

    INADDR_ANY是一个自动获取的内部ip,比如说127.0.0.1,这只是针对只有一个ip地址的情况,如果自己内部虚拟了网络,那么这个最后去手动填写。
    实际过程中我们赋值是:

    addr='127.0.0.1'
    inet_aton(addr,&addr_inet.sin_addr);
    

    功能如下:比如说我们写地址的时候是:127.0.0.1
    那么这个时候其实我们必须转换为32位的int类型,也就是32byte。
    inet_aton就是用来转换的,避免我们手动计算。

  • 相关阅读:
    thinkphp3.2.3版本在windows本地apache环境运行正常,上传到centos服务器apache环境中出现:thinkphp 上传根目录不存在!请尝试手动创建:uploads/
    [POI2013]LUK-Triumphal arch
    【背包问题】
    2016 acm香港网络赛 A题. A+B Problem (FFT)
    tomcat部署项目的三种方式
    仿照ArrayList自己生成的MyList对象
    使用回调函数实现回文判断
    关于angularjs的model的一些问题
    关于使用Tomcat服务器出现413错误的解决办法(Request Entity Too Large)
    关于angularjs+typeahead的整合
  • 原文地址:https://www.cnblogs.com/aoximin/p/12239458.html
Copyright © 2011-2022 走看看