套接字結(jié)構(gòu)
struct sockaddr_in
{
short int sin_family; //地址類型 AF_XXX(AF_UNIX,AF_INET和AF_NS)
unsigned short int sin_port; //16位端口號
struct in_addr sin_addr; //32位IP地址
char sin_zero[8]; //保留
} //端口號以及 Internet 地址使用的是網(wǎng)絡(luò)字節(jié)順序,需要通過函數(shù) htons 轉(zhuǎn)換
主機(jī)結(jié)構(gòu)
struct hostent
{ char *h_name ; //主機(jī)的正式名稱
char * *h_aliases ; //別名列表
int h_addrtype ; //主機(jī)地址類型:AF_XXX
lnt H_length; //主機(jī)地址長度:4 字節(jié)(32 位)
char * *h_addr_list;//主機(jī) IP 地址列表
}
函數(shù)庫
1. int socket(int domain,int type,int protocol);
函數(shù) socket 創(chuàng)建一個套接字描述符,如果失敗返回 -1.domain為地址類型AF_XXX,type為套接字類型,SOCK_STREAM(TCP),SOCK_DGRAM (UDP),SOCK_RAW(IP、ICMP);protocol 指定協(xié)議 0為默認(rèn)模式 。
2. int bind(int sockfd,struct sockaddr *hostaddr,int addrlen);
函數(shù)bind將本地地址與套接字綁定在一起,成功返回0,失敗為-1,并設(shè)置全局變量errno為錯誤類型
EADDRINUSER。
3. int connect( int sockfd,struct sockaddr *servaddr, int addrlen);
函數(shù)connect與服務(wù)器建立一個連接,成功返回 0,失敗返回- 1。servaddr 為遠(yuǎn)程服務(wù)器的套接字地址,包括服務(wù)器的 IP 地址和端口號;addrlen 為地址的長度。
4. int accept(int sockfd,struct sockaddr *addr,int *addrlen)
函數(shù)accept從listen的完成連接隊(duì)列中接收一個連接,如果連接隊(duì)列為空,則該進(jìn)程睡眠。
5. int listen(int sockfd,int backlog);
函數(shù)listen 將一個套接字轉(zhuǎn)換為傾聽套接字,執(zhí)行成功返回0,失敗為-1。backlog設(shè)置請求隊(duì)列的最大長度。
6. int write( int fd,char *buf,int len);
7. int read ( int fd,char *buf,int len);
函數(shù)read和write從套接字讀和寫數(shù)據(jù),成功返回數(shù)據(jù)量大小,否則返回 -1.buf 指定數(shù)據(jù)緩沖區(qū),len 指定接收或發(fā)送的數(shù)據(jù)量大小。
8. int close(int sockfd);
函數(shù)close關(guān)閉一個套接字描述符,成功返回0,失敗為-1。
9. struct hostent * gethostbyname( const char *hostname);
函數(shù) gethostbyname 查詢指定的域名地址對應(yīng)的 IP 地址,返回一個 hostent結(jié)構(gòu)的指針,如果不成功返回 NULL。
附帶函數(shù)
htons()
ntohs()
htonl()
ntohl()
在寫整型數(shù)據(jù)前,先轉(zhuǎn)換一下:
i= htonl(i);
write_data(s, &i, sizeof(i));
在讀整型數(shù)據(jù)后,再轉(zhuǎn)變回來:
read_data(s, &i, sizeof(i));
i= ntohl(i);
示例
#include /* obligatory includes */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 3490
int main( int argc,char *argv[] )
{ int sockfd,nbytes; //套接字描述符、讀入緩沖區(qū)的字節(jié)數(shù)
char buf[1024]; //緩沖區(qū)
struct hostent *he; //主機(jī)信息類型
struct sockaddr_in srvaddr;//Internet套接字結(jié)構(gòu)
if ( (1) argc!=2 )
{ perror( "調(diào)用參數(shù)為零,請輸入服務(wù)器的主機(jī)名!\n" ); exit(1);}
if ( (2) (he=gethostbyname(argv[1]))==NULL) //如果通過主機(jī)名沒有獲得對應(yīng)的主機(jī) 信息就提示用戶
{ perror("無法通過主機(jī)名獲得主機(jī)信息!\n" ); exit(1);}
if ( (3)(sockfd=socket(AF_INET,SOCK_STREAM.0))==-1 ) //在無法創(chuàng)建套接字時,
提示用戶
{ perror("無法創(chuàng)建套按字!\n" ); exit(1);}
bzero( &srvaddr,sizeof(srvaddr));//置空 srvaddr
srvaddr.sin_family = AF_INET;
srvaddr.sin_port=(4)htons(PORT) ;
srvaddr.sin_addr=(5)*((struct in_addr *)he->h_addr) ;
//設(shè)置套接字結(jié)構(gòu)的各項(xiàng)信息,其中的地址來自于域名查詢后的 hp 變量
if(connect( sockfd, (6)(struct sockaddr *)&srvaddr,sizeof( struct sockaddr))==-1 )
{ perror("連接失!\n" ); exit(1);}
//連接服務(wù)器,如果失敗則提示用戶
if (( nbytes = read ( sockfd,buf,MAXDATASIZE)) == -1 )
{ perror( "讀失!\n" ); exit(1);}
//從套容接字中讀出數(shù)據(jù)
buf[nbytes] = '\0';
printf("讀到的內(nèi)容:%s",buf) ;
close( sockfd) ;
//打印數(shù)據(jù)并關(guān)閉套接字
- 推薦給朋友
- 收藏此頁
·網(wǎng)絡(luò)工程師資料:網(wǎng)絡(luò)體系結(jié)構(gòu)-軟考網(wǎng)絡(luò)類題解 (2008-4-25 14:33:38)
·計算機(jī)網(wǎng)絡(luò)基礎(chǔ)網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)及優(yōu)缺點(diǎn)分析 (2008-2-22 14:04:32)
·網(wǎng)絡(luò)工程師必知:靜態(tài)路由協(xié)議配置方法 (2008-2-22 14:03:39)
·計算機(jī)網(wǎng)絡(luò)尼奎斯特 香農(nóng)公式例題解析 (2008-2-22 14:02:35)
·軟考復(fù)習(xí):因特網(wǎng)IP的分類、尋址規(guī)則及子網(wǎng)掩碼 (2008-2-22 13:57:21)
如果軟件水平考試網(wǎng)所轉(zhuǎn)載內(nèi)容不慎侵犯了您的權(quán)益,請與我們聯(lián)系,我們將會及時處理。如轉(zhuǎn)載本軟件水平考試網(wǎng)內(nèi)容,請注明出處。