TCP編程的服務(wù)器端一般步驟是
1、 創(chuàng)建一個(gè)socket,用函數(shù)socket();
2、 設(shè)置socket屬性,用函數(shù)setsockopt(); * 可選
3、 綁定IP地址、端口等信息到socket上,用函數(shù)bind();
4、 開啟監(jiān)聽,用函數(shù)listen();
5、 接收客戶端上來(lái)的連接,用函數(shù)accept();
6、 收發(fā)數(shù)據(jù),用函數(shù)send()和recv(),者read()和write();
7、 關(guān)閉網(wǎng)絡(luò)連接;
8、 關(guān)閉監(jiān)聽;
TCP編程的客戶端一般步驟是:
1、 創(chuàng)建一個(gè)socket,用函數(shù)socket();
2、 設(shè)置socket屬性,用函數(shù)setsockopt();* 可選
3、 綁定IP地址、端口等信息到socket上,用函數(shù)bind();* 可選
4、 設(shè)置要連接的對(duì)方的IP地址和端口等屬性;
5、 連接服務(wù)器,用函數(shù)connect();
6、 收發(fā)數(shù)據(jù),用函數(shù)send()和recv(),或者read()和write();
7、 關(guān)閉網(wǎng)絡(luò)連接;
UDP編程的服務(wù)器端一般步驟是:
1、 創(chuàng)建一個(gè)socket,用函數(shù)socket();
2、 設(shè)置socket屬性,用函數(shù)setsockopt();* 可選
3、 綁定IP地址、端口等信息到socket上,用函數(shù)bind()
4、 循環(huán)接收數(shù)據(jù),用函數(shù)recvfrom();
5、 關(guān)閉網(wǎng)絡(luò)連接;
UDP編程的客戶端一般步驟是:
1、 創(chuàng)建一個(gè)socket,用函數(shù)socket();
2、 設(shè)置socket屬性,用函數(shù)setsockopt();* 可選
3、 綁定IP地址、端口等信息到socket上,用函數(shù)bind();* 可選
4、 設(shè)置對(duì)方的IP地址和端口等屬性;
5、 發(fā)送數(shù)據(jù),用函數(shù)sendto();
6、 關(guān)閉網(wǎng)絡(luò)連接;
常用的網(wǎng)絡(luò)命令:
netstat
命令netstat是用來(lái)顯示網(wǎng)絡(luò)的連接,路由表和接口統(tǒng)計(jì)等網(wǎng)絡(luò)的信息.netstat有許多的選項(xiàng)我們常用的選項(xiàng)是 -an 用來(lái)顯示詳細(xì)的網(wǎng)絡(luò)狀態(tài).至于其它的選項(xiàng)我們可以使用幫助
telnet
telnet是一個(gè)用來(lái)遠(yuǎn)程控制的程序,但是我們完全可以用這個(gè)程序來(lái)調(diào)試我們的服務(wù)端程序的. 比如我們的服務(wù)器程序在監(jiān)聽8888端口,我們可以用telnet localhost 8888來(lái)查看服務(wù)端的狀況
數(shù)據(jù)結(jié)構(gòu)
1、地址結(jié)構(gòu)
struct sockaddr_in {
short int sin_family; /* 地址族 一般為AF-INET */
unsigned short int sin_port; /* 端口號(hào) */
struct in_addr sin_addr; /* IP地址 */
unsigned char sin_zero[8]; /* 填充0 以保持與struct sockaddr同樣大小 使用memset()或bzero()來(lái)填充*/
};
struct sockaddr {
unsigned short sa_family; /* 地址族, AF_xxx */
char sa_data[14]; /* 14 字節(jié)的協(xié)議地址 */
};
2、DNS結(jié)構(gòu)
struct hostent {
char *h_name; /* 主機(jī)的官方域名 */
char **h_aliases; /* 一個(gè)以NULL結(jié)尾的主機(jī)別名數(shù)組 */
int h_addrtype; /* 返回的地址類型,在Internet環(huán)境下為AF-INET */
int h_length; /*地址的字節(jié)長(zhǎng)度 */
char **h_addr_list; /* 一個(gè)以0結(jié)尾的數(shù)組,包含該主機(jī)的所有地址*/
};
操作函數(shù)
1、 socket:
創(chuàng)建socket 描述符
int socket(int domain, int type, int protocol);
domain=AF_INET,socket的類型,type=SOCK_STREAM 或SOCK_DGRAM,分別表示TCP連接和UDP連接;protocol=0。
返回一個(gè)整型socket描述符。
2.bind:
將socket描述符與你本機(jī)上的一個(gè)端口相關(guān)聯(lián)(僅用于服務(wù)器)
int bind(int sockfd,struct sockaddr *my_addr, int addrlen);
Sockfd是一個(gè)socket描述符
my_addr是一個(gè)指向包含有本機(jī)IP地址及端口號(hào)等信息的sockaddr類型的指針;
addrlen=sizeof(struct sockaddr)。
返回:成功=0;失敗=-1,errno=錯(cuò)誤號(hào)。
可以用下面的賦值自動(dòng)獲得本機(jī)IP地址和隨機(jī)獲取一個(gè)沒有被占用的端口號(hào):
my_addr.sin_port = 0; /* 系統(tǒng)隨機(jī)選擇一個(gè)未被使用的端口號(hào) */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本機(jī)IP地址 */
3.Connect:
與遠(yuǎn)端服務(wù)器建立一個(gè)TCP連接 (用于客戶端)
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
Sockfd是目的服務(wù)器的sockt描述符
serv_addr是包含目的機(jī)IP地址和端口號(hào)的指針。
返回:成功=0;失敗=-1,errno=錯(cuò)誤號(hào)。
4、Listen:
監(jiān)聽是否有服務(wù)請(qǐng)求 ,用于bind()后
int listen(int sockfd, int backlog);
Sockfd是Socket系統(tǒng)調(diào)用返回的socket 描述符;
backlog指定在請(qǐng)求隊(duì)列中允許的最大請(qǐng)求數(shù),缺省值為20。
返回:成功=0;失敗=-1,errno=錯(cuò)誤號(hào)。
5.accept:
接受來(lái)自客戶的請(qǐng)求
int accept(int sockfd, void *addr, int *addrlen);
sockfd是被監(jiān)聽的socket描述符,
addr 是指向sockaddr_in變量的指針,存放客戶主機(jī)的信息 ;
addrten 指向值為sizeof(struct sockaddr_in)的整型指針變量。
返回:成功返回一個(gè)新的socket描述符,來(lái)供這個(gè)新連接來(lái)使用。 錯(cuò)誤發(fā)生時(shí)返回一個(gè)-1并且設(shè)置相應(yīng)的errno值。
6.Send:
在連接(TCP)的socket方式下發(fā)送信息
int send(int sockfd, const void *msg, int len, int flags);
Sockfd是用來(lái)傳輸數(shù)據(jù)的socket描述符
msg是一個(gè)指向要發(fā)送數(shù)據(jù)的指針。
Len是以字節(jié)為單位的數(shù)據(jù)的長(zhǎng)度。
flags一般情況下置為0。
7.recv:
在連接(TCP)的socket方式下接收數(shù)據(jù)
int recv(int sockfd,void *buf,int len,unsigned int flags);
Sockfd是接受數(shù)據(jù)的socket描述符;
buf 是存放接收數(shù)據(jù)的緩沖區(qū);
len是緩沖的長(zhǎng)度。
Flags也被置為0。
返回:實(shí)際上接收的字節(jié)數(shù),如果連接中止,返回0,。出現(xiàn)錯(cuò)誤時(shí),返回-1并置相應(yīng)的errno值。
8.sendto:
在在無(wú)連接(UDP)的socket方式下發(fā)送數(shù)據(jù)
int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
to表示目地機(jī)的IP地址和端口號(hào)信息
tolen=sizeof (struct sockaddr)。
返回:實(shí)際發(fā)送的數(shù)據(jù)字節(jié)長(zhǎng)度或在出現(xiàn)發(fā)送錯(cuò)誤時(shí)返回-1。
9.Recvfrom()
在無(wú)連接(UDP)的socket方式下接收數(shù)據(jù)
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
from 保存源機(jī)的IP地址及端口號(hào)。
fromlen=sizeof(struct sockaddr)。
返回:實(shí)際存入from中的數(shù)據(jù)字節(jié)數(shù)。當(dāng)出現(xiàn)錯(cuò)誤時(shí)返回-1,并置相應(yīng)的errno。
10.close()
釋放socket,停止任何數(shù)據(jù)操作
close(sockfd);
11.shutdown:
單向關(guān)閉連接
int shutdown(int sockfd,int how);
how可以設(shè)為下列值:
·0-------不允許繼續(xù)接收數(shù)據(jù)
·1-------不允許繼續(xù)發(fā)送數(shù)據(jù)
·2-------不允許繼續(xù)發(fā)送和接收數(shù)據(jù),均為允許則調(diào)用close ()
shutdown在操作成功時(shí)返回0,在出現(xiàn)錯(cuò)誤時(shí)返回-1(并置相應(yīng)errno)。
12. gethostbyname:
域名和IP地址的轉(zhuǎn)換
struct hostent *gethostbyname(const char *name);
13.inet_pton函數(shù):
將點(diǎn)分十進(jìn)制串轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)序二進(jìn)制值,此函數(shù)對(duì)IPv4地址和IPv6地址都能處理。
int inet_pton(int family,const char * strptr,void * addrptr);