• 初探网络编程


    网络编程是Linux开发中的重要部分,Linux环境网络编程是基于Socket的C语言编程,Socket本意是插座,它在网络中描述不同计算机之间通信的方式。网络通信中可以使用TCP或者UDP协议,对于我们来说不会太关心协议本身的细节,而是更关注不同主机之间传输的过程,因此制定了一种用于网络传输数据的编程接口,称为套接字(Socket)。

    Socket编程接口内容很多,我自己看了一部分之后感觉学习过程中需要分析数据通信的过程,理解网络中的基础知识才不至于混肴。下面是一些网络编程的基本操作。 

    1、网络编程的基本概念

    1. IP地址
      网络中的计算机均有唯一IP地址,用来标识它在网路中的身份,我们常见的就是点分十进制写法的IP地址,如“210.187.77.10”。实际上在通信过程中IP地址是以整型方式存储的,如“193921391”。我们看到的点分十进制IP地址是由网络整型IP转为点分IP字符串得到的。
    2. 端口 网络中的端口不同于硬件中的端口,IP地址标识了网络世界的主机,端口号指明了主机中的具体网络程序,比如FTP端口号是21,端口范围是0~65535,低于256的是系统保留端口。
    3. 域名 域名是用来代替IP地址来直观标识计算机的直观名称,如百度IP http://www.baidu.com. ping www.baidu.com 表明域名指向的IP地址是202.108.22.43.
    4. TCP/UDP
      TCP与UDP是两种不同的网络传输方式,使用IP和Port,要使用一种约定方式进行数据传输,TCP/UDP就是网络中两种数据传输约定,主要区别是数据传输时是否进行连接。 

    2、套接字

    区别不同应用程序进程间通信和连接,只要使用三个参数:通信的目的IP,使用的传输层协议(TCP/IP)和端口号,编程时这三个参数构成一个套接字接口。 

    C程序进行套接字编程时,使用sockaddr_in数据类型,这是系统定义的结构体,用于保存套接字信息,定义如下: 

    struct socketaddr
    {
        usigned short int sin_family;
        uint16_t sin_port;
        struct in_addr sin_addr;
        unsigned char sin_zero[8];
    }
    
    • sin_family:指定通信的地址类型,如果是TCP/IP通信,该值为AF_INET
    • sin_port:套接字使用的端口号。
    • sin_addr:要访问的IP地址。
    • sin_zero:未使用的字段,填充为0。

    套接字的类型

    • 流套接字(SOCK_STREAM)
      面向连接的可靠数据通信方式,即TCP协议;
    • 数据报套接字(SOCK_DGRAM) 面向无连接的数据通信方式,即UDP协议;
    • 原始套接字(SOCK_RAW) 前面两种是系统定义的,所有信息都要按照这种方式金星封装,原始套接是没有经过处理的IP数据包,可以按照自己程序的要求进行封装。 

    3、域名与IP

    域名取得相对应的IP地址
    struct hostent *gethostbyname(const char *name);
    name是保存域名的字符串,函数返回指向hostent结构体的指针,hostent结构体定义如下: 

    struct hostent
    {
        char *h_name;
        char **h_aliases;
        int h_addrtype;
        int h_length;
        char **h_addr_list;
    }
    

    h_name 主机名称
    h_aliases 主机别名
    h_addrtype 主机名类型
    h_length 地址长度
    h_addr_list 主机IP 

    IP取得相对应的域名
    struct hostent *gethostbyaddr(const void *addr,socklen_t len,int type);
    参数列表中addr是保存IP地址的字符串,len是IP地址长度,type一般为AF_INET

    4、网络协议

    网络协议是指不同计算机之间进行通信的约定,在进行网络编程时需要遵循这些协议。 

    • 由协议名取得协议数据
      struct protoent *getprotobyname(char *name);
      name是一个协议名称字符串,返回一个protoent结构体指针,protoent定义如下: 
    struct protoent
    {
        char *p_name;
        char **p_aliases;
        int p_proto;
    }
    

    p_name:协议的名称
    p_aliases:协议的别名
    p_proto:协议的序号
    struct protoent *pro=getprotobyname(“tcp”);

    • 由协议编号取得协议数据
      struct protoent *pro=getprotobynumber(“tcp”);

    • 获得系统支持的所有协议
      struct protoent *pro

    while(pro=getprotoent())
    {
        ...
    }
    

    5、网络服务

    所谓网络服务,指的是网络上的计算机通过运行程序,为其他计算机提供信息或运算的功能。 

    • 函数getserent的作用是获取系统所支持的服务,getservent函数定义如下
      struct servent *getservent(void);
      servent结构体如下 
    struct servent
    {
        char *s_name;
        char **s_aliases;
        int s_port;
        char *s_proto;
    }
    

    s_name:服务名
    s_aliases:服务别名
    s_port:服务端口号
    s_proto:服务使用的协议 

    • 服务名称获取服务
      struct servent *getservbyname(char *name,char *proto);

    • 端口取得服务名称
      struct servent *getservbyport(int port,char *proto);

    6、网络地址的转换

    网络地址本是用32位二进制数来表示的,为了记忆方便,可以用点分十进制数来表示IP地址。同时,网络传输与计算机内部的字符存储方式是不同的,需要相关函数将端口号进行转换。 

    • 网络地址转换为整型
      函数inet_addr可以将网络IP转为十进制长整型数。
      long inet_addr(char *cp);
      参数cp是一个IP地址字符串,使用这个函数前需要包含头文件 
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    • 长整型地址转为网络地址
      函数inet_ntoa可以将整形地址转为网络地址,进而转换为点分十进制地址。
      char *inet_ntoa(struct in_addr in);
      使用实例: 
    struct in_addr ip;
    ip.s_addr=16885952;
    printf("%s",inet_ntoa(ip));
    
    • 主机字符顺序与网络字符顺序的转换
      计算机中的整型与网络中的整型进行交换时,需要相关的函数进行交换。这些函数如下 
    uint32_t htonl(uint32_t hostlong)
    uint16_t htons(uint16_t hostshort)
    uint32_t ntohl(uint32_t netlong)
    uint16_t ntohs(uint16_t netshort)
    

    7、错误处理

    • herror函数显示错误
      函数herror可以显示上一个网络函数发生的错误,定义如下
      void herror(const char *s);
      函数参数是字符串,调用函数是首先输出字符串信息,然后输出错误信息 
    char s[]="error:";
    herror(s);
    
    • 捕获错误编号
      网络程序中使用下面的语句来捕获错误编号:
      extern int h_errno;
      捕获到错误编号后,可以用hstrerror函数输出错误信息 
    char *hstrerror(int err)   //err是上面捕获的错误编号h_errno
    

    以上是socket编程的基础知识!

  • 相关阅读:
    saltstack学习-1:saltstack介绍、部署、常见问题处理
    CentOS 6.8使用Subversion + Usvn 搭建版本管理服务器+常用钩子
    matlab快捷键
    转行小白成长路-java篇
    转行小白成长路-java篇
    转行小白成长路-java篇
    转行小白成长路-java篇
    转行小白成长路-java篇
    转行小白成长路-java篇
    转行小白成长路-java篇
  • 原文地址:https://www.cnblogs.com/limicheng/p/4009171.html
Copyright © 2020-2023  润新知