• 字数据网络编程基础


    改章节是一篇关于字数据的帖子

         

        说明:只供学习交流,转载请注明出处

         

         

        一,套接字编程基本

        

        套接字,英文为socket,是一种双向的通信端口。位于网络中的主机通过连接的套接字供给的接口进行数据传输。套接字是一种应用标准UNIX文件描述符(file descriptor)与其他程序通信的方法。套接字可以看做是处于不同主机之间的两个程序的通信连接端点。一方面程序将要传输的信息写入套接字中,而另一方面则通过读取套接字的数据来取得传输的信息。

         

        字和数据

         

        

        上图为应用套接字进行通信的示意图。假设存在两台主机AB,在主机A中存在进程C,主机B中存在进程D,当进程C需要将数据送到进程D中的时候,首先将数据写到套接字中,而进程D通过读取套接字来取得进程C发送的消息。

         

        在网络中不同计算机是通过IP地址来辨别的,也就是说,要将数据由主机A发送到主机B,只要晓得主机BIP地址就可以确定数据要发送的目的地。但是在主机AB中不可能只有进程C和进程D两个进程。主机B在收到数据主机A发送来的数据以后,如何才能确定该数据是发送给进程D?因此,还需要某种标识信息,用于描述网络通信数据发送的进程。TCP/IP协议提出了协议端口观点,用于标识通信的进程。

         

        当进程与某个端口绑定后,操作系统会将收到给该端口的数据送往该进程。与文件描述符类似,每一个端口都有被称为端口号的整数类型的标识符,该标识符用于辨别不同的端口。不同协议可以应用雷同的端口号进行数据传输。例如,TCP应用了344的端口号,UDP同样可以应用344端口号进行数据传输。

         

        端口号为一个16位的无符号整数,其取值范围为0~65535。低于256的端口被作为操作系统的保留端口号,重要用于系统进程的通信,不在这一范围的端口号被称为自由端口号,可以由进程自由的应用。

         

        二,套接字编程相关的数据结构

        在开辟应用套接字进行通信的程序时,常会用到sockaddr数据结构或sockaddr_in数据结构。sockaddr数据结构用于保存套接字的地址信息,具体定义如下:

        struct sockaddr {

              sa_family_t  sa_family;     /*address family, AF_xxx      */

              char          sa_data[14]; /* 14 bytes of protocol address    */

        };

        sa_family:用于指定地址族,如果是TCP/IP通信,该值取PF_INET

        sa_data:用于保存套接字的IP地址和端口号信息。

         

        sockaddr_in数据结构与sockaddr类似,该结构体的定义如下:

        struct sockaddr_in {

         sa_family_t          sin_family;   /* Address family         */

         __be16           sin_port; /* Port number              */

         struct in_addr  sin_addr;    /* Internet address        */

        unsigned char sin_zero[8];

        };

        sin_family:用于指定地址族。

        sin_port:套接字通信的端口号。

        sin_addr:通信的IP地址。

        sin_zero[8]:用于填充0,保存于structsockaddr同样巨细。

        由于sockaddr数据结构与sockaddr_in数据结构的巨细是雷同的,指向sockaddr_in的指针可以通过强制转换,转换成指向sockaddr结构的指针。

         

         

        三,套接字类型

        经常使用的TCP/IP协议的3中套接字类型如下所示:

        1):流套接字(SOCK_STREAM):流套接字用于供给面向连接、可靠的数据传输服务。该服务将保证数据可以实现无差错、无重复发送,并按次序接收。流套接字之所以可以实现可靠的数据服务,原因在于其应用了传输控制协议,即TCPTheTransmission Control Protocol)协议。

        2):数据报套接字(SOCK_DGRAM):数据报套接字供给了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程当中丧失或出现数据重复,且没法保证次序的接收到数据。数据报套接字应用UDPUser DatagramProtocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丧失情况,需要在程序中做相应的处置。

        每日一道理
    毅力,是千里大堤一沙一石的凝聚,一点点地累积,才有前不见头后不见尾的壮丽;毅力,是春蚕吐丝一缕一缕的环绕,一丝丝地坚持,才有破茧而出重见光明的辉煌; 毅力,是远航的船的帆,有了帆,船才可以到达成功的彼岸。

        3):原始套接字(SOCK_RAW):原始套接字与标准套接字(流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处置的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须应用原始套接字。

         

        四,big_endianlittle_endian

        不同体系的CPU在内存中的数据存储往往存在着差异。例如IntelX86系列处置器将低序字节存储在起始地址,而一些RISC架构的处置器,如IBM370主机应用的PowerPCMotorola公司生产的CPU,都将高序字节存储在起始位置。这两种不同的存储方法被称为little-endianbig-endian

         

        little-endianX86系列CPU的数据存储方法,即将低序的部分存储在前面。而big-endian是将高序部分存储在前面。例如,要存储0xF432little-endian将以32F4存储,而应用big-endian与此相反,将存储为F432,如下图所示:

         

        字和数据

        字和数据

         

        上面我们将用两种方法来查看我们所应用的处置器是big-endian还是little-endian

        1):利用联合的特点:联合中的数据成员是同享存储空间的,所分配的空间为数据成员中最大所需的内存数。程序定义了名为endian_un的联合体,其中包含两个数据成员,一个是short类型的数据成员(在32位系统上,short类型的长度是2个字节),一个是字符类型的字符数组,字符数组的元素个数为short类型的字节数。程序将var赋值为0x0102。由于联合结构的特点,bits字符串数组中同样存储了0x0102这一数值。通过判断字符串中的低位和高位存储的内容,就可以晓得系统是little-endian还是big-endian的。

        2):通过强制类型转换实现:程序中通过取flag变量的地址,取得起始空间的存储内容。如果起始空间存储的数据的低位内容,则表示存储方法little-endian,否则为big-endian

         

        程序如下:

         

    #include <stdio.h>
    
    int is_little_endian(void)
    {
        unsigned short flag = 0x4321;
        
        if (*(unsigned char *)&flag == 0x21)
        {
            return (1);
        }    
        else
        {
            return (0);
        }    
    }    
    
    int main(void)
    {
        union endian_un
        {
            short var;
            char bits[sizeof(short)];
        };
        
        union endian_un flag;
        
        flag.var = 0x0102;
        
        if (sizeof(short) == 2)
        {
            if (flag.bits[0]==1 && flag.bits[1]==2)
            {
                printf("Judged by first method, big-endian\n");
            }    
            else if(flag.bits[0]==2 && flag.bits[1]==1)
            {
                printf("Judged by first method, little-endian\n");
            }    
            else
            {
                printf("Cannot determine the type\n");        }    
        }    
        
        
        if (is_little_endian())
        {
            printf("Judged by second method, little-endian\n");
        }    
        else
        {
            printf("Judged by second method, big-endian\n");
        }    
        
        system("PAUSE");
        return (0);
        
    }    
    
    运行结果:
    Judged by first method, little-endian
    Judged by second method, little-endian
    请按任意键继续. . .

        
     

        之所以介绍big-endianlittle-endian,是因为这一数据存储方法不仅影响程序在不同硬件平台中的移植,而且在网络中也要考虑字节次序的问题。为了避免兼容性的问题,网络中的数据传输都应用了从高到底的次序存储的方法。因此,如果要将数据从低位字节优先(little-endian)的机器上发往网络,必须首先进行转换。而big-endian的机器是不需要转换的。

        Linux系统供给了htonshtonlntohsntohl4个函数用于进行字节次序的转换。其中,hhost的缩写,n表示network。最后一个字符如果是s,表示short类型,如果是l,表示为long类型。4个函数的具体定义如下:

        uint32_t  htonl(uint32_t  hostlong);

        uint16_t  htons(uint16_t  hostshort);

        uint32_t  ntohl(uint32_t  netlong);

        uint32_t  ntohs(uint16_t netshort);

         

        htonl/htons:表示主机字节次序转换成网络字节次序,htonl函数和htons函数的区别在于参数长度存在差异。

        ntohl/ntohs:表示网络字节次序转换成主机字节次序,ntohl函数和ntohs函数的区别在于参数长度存在差异。

         

         

         

         

         

         

         

    文章结束给大家分享下程序员的一些笑话语录: 打赌
    飞机上,一位工程师和一位程序员坐在一起。程序员问工程师是否乐意和他一起玩一种有趣的游戏。工程师想睡觉,于是他很有礼貌地拒绝了,转身要睡觉。程序员坚持要玩并解释说这是一个非常有趣的游戏:"我问你一个问题,如果你不知道答案,我付你5美元。然后你问我一个问题,如果我答不上来,我付你5美元。"然而,工程师又很有礼貌地拒绝了,又要去睡觉。  程序员这时有些着急了,他说:"好吧,如果你不知道答案,你付5美元;如果我不知道答案,我付50美元。"果然,这的确起了作用,工程师答应了。程序员就问:"从地球到月球有多远?"工程师一句话也没有说,给了程序员5美元。  现在轮到工程师了,他问程序员:"什么上山时有三条腿,下山却有四条腿?"程序员很吃惊地看着工程师,拿出他的便携式电脑,查找里面的资料,过了半个小时,他叫醒工程师并给了工程师50美元。工程师很礼貌地接过钱又要去睡觉。程序员有些恼怒,问:"那么答案是什么呢?"工程师什么也没有说,掏出钱包,拿出5美元给程序员,转身就去睡觉了。

    --------------------------------- 原创文章 By
    字和数据
    ---------------------------------

  • 相关阅读:
    简易文法
    词法分析实验报告
    0909上级作业
    vs2008的快捷键
    一道C++笔试题说一些知识
    Effective C++读书笔记
    鼠标拖动物体DEMO
    CFileDialog类的使用以及在非MFC程序下使用MFC的类资源
    3D制作魔方
    使用DXUT框架简单处理鼠标事件
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3112998.html
Copyright © 2020-2023  润新知