初探網絡編程

網絡編程是Linux開發中的重要部分,Linux環境網絡編程是基於Socket的C語言編程,Socket本意是插座,它在網絡中描述不一樣計算機之間通訊的方式。網絡通訊中可使用TCP或者UDP協議,對於咱們來講不會太關心協議自己的細節,而是更關注不一樣主機之間傳輸的過程,所以制定了一種用於網絡傳輸數據的編程接口,稱爲套接字(Socket)。編程

Socket編程接口內容不少,我本身看了一部分以後感受學習過程當中須要分析數據通訊的過程,理解網絡中的基礎知識才不至於混餚。下面是一些網絡編程的基本操做。 網絡

一、網絡編程的基本概念socket

  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就是網絡中兩種數據傳輸約定,主要區別是數據傳輸時是否進行鏈接。

二、套接字tcp

區別不一樣應用程序進程間通訊和鏈接,只要使用三個參數:通訊的目的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。

套接字的類型ui

  • 流套接字(SOCK_STREAM)
    面向鏈接的可靠數據通訊方式,即TCP協議;
  • 數據報套接字(SOCK_DGRAM) 面向無鏈接的數據通訊方式,即UDP協議;
  • 原始套接字(SOCK_RAW) 前面兩種是系統定義的,全部信息都要按照這種方式金星封裝,原始套接是沒有通過處理的IP數據包,能夠按照本身程序的要求進行封裝。

三、域名與IP指針

域名取得相對應的IP地址
struct hostent *gethostbyname(const char *name);
name是保存域名的字符串,函數返回指向hostent結構體的指針,hostent結構體定義以下: code

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

四、網絡協議

網絡協議是指不一樣計算機之間進行通訊的約定,在進行網絡編程時須要遵循這些協議。

  • 由協議名取得協議數據
    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())
{
    ...
}

五、網絡服務

所謂網絡服務,指的是網絡上的計算機經過運行程序,爲其餘計算機提供信息或運算的功能。

  • 函數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);

六、網絡地址的轉換

網絡地址本是用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)

七、錯誤處理

  • 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編程的基礎知識!

相關文章
相關標籤/搜索