伺服器和客戶機的資訊函式以及讀寫函式

2021-07-25 17:36:59 字數 3613 閱讀 2072

1.伺服器和客戶機的資訊函式

(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,其他幾個函式的意義也差不多。

(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) 字串的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的格式。

(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。為了得到指定的埠號的服務,我們可以呼叫第

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

2. 完整的讀寫函式

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

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

(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);}

(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);

}(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型別的資料傳遞.接收的時候也是一樣的,注意的是我們沒有必要

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

簡單的客戶機伺服器投射模擬

下面模擬了,簡單的客戶機伺服器投射模擬的過程。客戶機像伺服器傳送資料,伺服器接受到資料後,傳送回給客戶機。再由客戶機列印出來。網路方面 伺服器 socket af inet,sock stream,0 af inet表示ipv4,sock stream表示基於位元組流的,0表示協議由前面兩個引數組合...

簡單的客戶機伺服器投射模擬

下面模擬了,簡單的客戶機伺服器投射模擬的過程。客戶機像伺服器傳送資料,伺服器接受到資料後,傳送回給客戶機。再由客戶機列印出來。網路方面 伺服器 socket af inet,sock stream,0 af inet表示ipv4,sock stream表示基於位元組流的,0表示協議由前面兩個引數組合...

利用伺服器將客戶機加入域

1 netdom 系統支援工具,使用前需先行安裝 光碟 support tools suptools.msi 2 新增計算機到域 在域控制器上執行以下命令 netdom join 10.4.122.3 domain nc.bmcc.com.cn userd administrator passwor...