Linux网络编程【2】

来源:互联网 发布:cookie登录 php 编辑:程序博客网 时间:2024/06/05 02:52

Linux网络编程【2】

1.概述

  • 搭建好了linux环境和c/c++开发环境后,终于到了可以写代码的时候了,但是开始写代码之前,必须要比较熟悉下面三点内容:
    • 熟悉c/c++编程语言
    • 熟悉linux系统
    • 熟悉计算机网络(TCP/IP协议等),TCP/IP详解

2.主机字节序和网络字节序

  • cpu一次能装载4个字节(32位机器),即一个整数,这4个字节在内存中的排列顺序就是字节序问题。
  • 大端字节序:指高位字节(23-31bit)存储在内存的低地址处,低位字节(0-7bit)存储在高地址处。
  • 小端自己序:指高位字节(23-31bit)存储在内存的高地址处,低位字节(0-7bit)存储在低地址处。
  • 现代pc机大多数是小端字节序,但如果两台不同的机器传递数据时,接收端并不知道对方的数据是使用哪种字节序,所以可能会出错,解决办法是:发送端总是将要发送的数据转换成大端字节序之后才发送,这样接收方就默认这个数据是大端字节序,便可以正确处理,所以,我们也将大端字节序称作为网络字节序
  • 以下是相关字节序转换函数,需#include<netinet/in.h>
    unsigned long int htonl(uint32_t hostlong);//32位的主机字节序转换到网络字节序
    unsigned short int htons(uint16_t hostshort);//16位的主机字节序转换到网络字节序
    unsigned long int ntohl(uint32_t netlong);//32位的网络字节序转换到主机字节序
    unsigned short int ntohs(uint16_t netshort);//16位的网络字节序转换到主机字节序

    htonl表示 host to network long ,将长整型的主机字节序数据转换为网络字节序数据。其他同理,通常长整型(32bit)用来转换ip地址,短整型(16bit)用来转换端口号。

3.socket地址结构体

  • socket网络编程接口中,通用socket地址的结构体:
    struct sockaddr{
    unisgned short as_family; //地址族类型变量
    char sa_data[14]; //存放socket地址值
    };
  • 专用于ipv4的socket地址结构体:
    struct sockaddr_in{
    unsigned short sin_family; //表示地址族类型,一般为AF_INET,表示tcp/ipv4协议族
    unsigned short int sin_port; //端口号
    struct in_addr sin_addr; //ipv4地址,用网络字节序表示
    unsigned char sin_zero[8]; //下面解释
    }
  • sin_zero[8]的相关解释:这八个字节是预留出来的,是为了让sockaddr_in结构体和sockaddr拥有一样的大小。以免出现转换异常,因为大部分网络字节使用的是sockaddr,当你使用sendto函数来发送数据时,必须将sockaddr_in结构体转换为sockaddr结构体,这样就必须要这两个结构体的大小一致。一般会struct sockaddr_in my_addr;bzero(&(my_addr.sin_zero),8);将其指向指针的前八个字节清空,详情戳这里

4.IP地址转换函数

-我们通常用点分法来表示ip地址,即十进制数据(如192.168.10.93),但编程中我们需要将这些十进制字符串转换为二进制数据,计算机才能识别,记录日志则相反。相关函数如下:

    int inet_pton(int af,char* src,void* dst)    const char* inet_ntop(int af,const void* src,char* dst,socklen_t cnt)

inet_pton函数将字符串(十进制的ipv4,十六进制的ipv6)表示的ip地址src转换为网络字节序表示的ip地址,将转换结构存于dst指针指向的内存里面,af是地址族类型。inet_ntop则进行相反的操作,前三个参数相同,后一个参数cnt表示指定目标存储单元的大小(ipv4为16,ipv6为46,都是宏定义的)。

5.创建socket

  • 面向连接基本步骤如下(tcp):
    • 服务器:socket()–>bind()–>listen()–>accept()–>read()–>write()
    • 客户端:socket()–>connect()–>write()–>read()
  • 无连接基本步骤如下:
    • 服务器:socket()–>bind()–>recvfrom()–>sendto()
    • 客户端:socket()–>bind()–>sendto()–>recvfrom()
  • 详细代码见第6点的 第一个博客

6.相关博客

  • linux网络编程常用函数详解与实例(socket–>bind–>listen–>accept)
  • Linux网络编程入门 (转载)
  • linux socket常用函数
1 0