zoukankan      html  css  js  c++  java
  • 初探网络编程

    网络编程是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编程的基础知识!

  • 相关阅读:
    Visual Studio 2010使用Visual Assist X的方法
    SQL Server 2000 评估版 升级到 SQL Server 2000 零售版
    双网卡多网络单主机同时访问
    开发即过程!立此纪念一个IT新名词的诞生
    delphi dxBarManager1 目录遍历 转为RzCheckTree2树
    5320 软件集合
    delphi tree 从一个表复制到另一个表
    DELPHI 排课系统课表
    长沙金思维 出现在GOOGLE的 金思维 相关搜索里啦!!
    如何在DBGrid的每一行前加一个单选框?
  • 原文地址:https://www.cnblogs.com/limicheng/p/4009171.html
Copyright © 2011-2022 走看看