Linux網路程式設計入門 2

2021-07-14 23:02:40 字數 4438 閱讀 7858

linux網路程式設計--3. 伺服器和客戶機的資訊函式

這一章我們來學習轉換和網路方面的資訊函式. 

3.1 位元組轉換函式 

在網路上面有著許多態別的機器,這些機器在表示資料的位元組順序是不同的, 比如i386晶元是低位元組在記憶體位址的低端,

高位元組在高階,而alpha晶元卻相反. 為了統一起來,在linux下面,有專門的位元組轉換函式. 

unsigned long  int htonl(unsigned long  int hostlong)

unsigned short int htons(unisgned short int hostshort)

unsigned long  int ntohl(unsigned long  int netlong)

unsigned short int ntohs(unsigned short int netshort)

在這四個轉換函式中,h 代表host, n 代表 network.s 代表short l 代表long 

第乙個函式的意義是將本機器上的long資料轉化為網路上的long. 其他幾個函式的意義也差不多.

3.2 ip和網域名稱的轉換 

在網路上標誌一台機器可以用ip或者是用網域名稱.那麼我們怎麼去進行轉換呢?

struct hostent *gethostbyname(const char *hostname)

struct hostent *gethostbyaddr(const char *addr,int len,int type)

在中有struct hostent的定義

struct hostent

#define h_addr h_addr_list[0]  /* 主機的第乙個ip位址*/

gethostbyname可以將機器名(如 linux.yessun.com)轉換為乙個結構指標.在這個結構裡面儲存了網域名稱的資訊 

gethostbyaddr可以將乙個32位的ip位址(c0a80001)轉換為結構指標.

這兩個函式失敗時返回null 且設定h_errno錯誤變數,呼叫h_strerror()可以得到詳細的出錯資訊

3.3 字串的ip和32位的ip轉換. 

在網路上面我們用的ip都是數字加點(192.168.0.1)構成的, 而在struct in_addr結構中用的是32位的ip, 

我們上面那個32位ip(c0a80001)是的192.168.0.1 為了轉換我們可以使用下面兩個函式

int inet_aton(const char *cp,struct in_addr *inp)

char *inet_ntoa(struct in_addr in)

函式裡面 a 代表 ascii n 代表network.第乙個函式表示將a.b.c.d的ip轉換為32位的ip,

儲存在 inp指標裡面.第二個是將32位ip轉換為a.b.c.d的格式.

3.4 服務資訊函式 

在網路程式裡面我們有時候需要知道埠.ip和服務資訊.這個時候我們可以使用以下幾個函式

int getsockname(int sockfd,struct sockaddr *localaddr,int *addrlen)

int getpeername(int sockfd,struct sockaddr *peeraddr, int *addrlen)

struct servent *getservbyname(const char *servname,const char *protoname)

struct servent *getservbyport(int port,const char *protoname)

struct servent

一般我們很少用這幾個函式.對應客戶端,當我們要得到連線的埠號時在connect呼叫成功後使用可得到 

系統分配的埠號.對於服務端,我們用inaddr_any填充後,為了得到連線的ip我們可以在accept呼叫成功後 使用而得到ip位址. 

在網路上有許多的預設埠和服務,比如埠21對ftp80對應www.為了得到指定的埠號的服務 我們可以呼叫第四個函式,

相反為了得到埠號可以呼叫第三個函式.

3.5 乙個例子

code:  [copy to clipboard]

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc ,char **argv)

argv++;

for(;*argv!=null;argv++)

else 

if(host==null)

printf("official host name %s\n",host->h_name);

printf("name aliases:");

for(alias=host->h_aliases;*alias!=null;alias++)

printf("%s ,",*alias);

printf("\nip address:");

for(alias=host->h_addr_list;*alias!=null;alias++)

printf("%s ,",inet_ntoa(*(struct in_addr *)(*alias)));}}

在這個例子裡面,為了判斷使用者輸入的是ip還是網域名稱我們呼叫了兩個函式,第一次我們假設輸入的是ip所以呼叫inet_aton, 

失敗的時候,再呼叫gethostbyname而得到資訊.

(四)linux網路程式設計--4. 完整的讀寫函式

一旦我們建立了連線,我們的下一步就是進行通訊了.在linux下面把我們前面建立的通道看成是檔案描述符,

這樣伺服器端和客戶端進行通訊時候,只要往檔案描述符裡面讀寫東西了. 就象我們往檔案讀寫一樣.

4.1 寫函式write 

ssize_t write(int fd,const void *buf,size_t nbytes)

write函式將buf中的nbytes位元組內容寫入檔案描述符fd.成功時返回寫的位元組數.失敗時返回-1. 並設定errno變數. 

在網路程式中,當我們向套接字檔案描述符寫時有倆種可能.

1)write的返回值大於0,表示寫了部分或者是全部的資料.

2)返回的值小於0,此時出現了錯誤.我們要根據錯誤型別來處理.

如果錯誤為eintr表示在寫的時候出現了中斷錯誤. 

如果為epipe表示網路連線出現了問題(對方已經關閉了連線). 

為了處理以上的情況,我們自己編寫乙個寫函式來處理這幾種情況.

int my_write(int fd,void *buffer,int length)

bytes_left-=written_bytes;

ptr+=written_bytes;     /* 從剩下的地方繼續寫  */

}return(0);

}4.2 讀函式read 

ssize_t read(int fd,void *buf,size_t nbyte) read函式是負責從fd中讀取內容.當讀成功時, 

read返回實際所讀的位元組數,如果返回的值是0 表示已經讀到檔案的結束了,小於0表示出現了錯誤.

如果錯誤為eintr說明讀是由中斷引起的, 

如果是econnrest表示網路連線出了問題. 和上面一樣,我們也寫乙個自己的讀函式.

int my_read(int fd,void *buffer,int length)

else if(bytes_read==0)

break;

bytes_left-=bytes_read;

ptr+=bytes_read;

}return(length-bytes_left);

}4.3 資料的傳遞 

有了上面的兩個函式,我們就可以向客戶端或者是服務端傳遞資料了.比如我們要傳遞乙個結構.可以使用如下方式

/*  客戶端向服務端寫 */

struct my_struct my_struct_client;

write(fd,(void *)&my_struct_client,sizeof(struct my_struct);

/* 服務端的讀*/ 

char buffer[sizeof(struct my_struct)];

struct *my_struct_server;

read(fd,(void *)buffer,sizeof(struct my_struct)); 

my_struct_server=(struct my_struct *)buffer;   

在網路上傳遞資料時我們一般都是把資料轉化為char型別的資料傳遞.接收的時候也是一樣的 注意的是我們沒有必要在網路上傳

遞指標(因為傳遞指標是沒有任何意義的,我們必須傳遞指標所指向的內容)

linux網路程式設計入門

服務端 server.c include include include include include include define portnum 3333 隨便定義乙個埠 int main 設定要繫結的位址,對server addr初始化 bzero server addr,sizeof st...

linux網路程式設計2

位元組序轉換 不同型別的 cpu 對變數的位元組儲存順序可能不同 有的系統是高位在前,低位在後,而有的系統是低位在前,高位在後,而網路傳輸的資料順序是一定要統一的。所以當內部位元組儲存順序和網路位元組順序不同時,就一定要進行轉換 網路位元組順序是tcp ip中規定好的一種資料表示格式,它與具體的cp...

Linux網路程式設計 (2)網路程式設計基礎

一 ip位址 1 ip的概念 internet protocol 網路之間互連的協議 也就是為計算機網路相互連線進行通訊而設計的協議。在 網際網路中,它是能使連線到網上的所有計算機網路實現相互通訊的一套規則,規定了 計算機在網際網路上進行通訊時應當遵守的規則。任何廠家生產的計算機系統,只要遵守ip協...