版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第5講Socket網(wǎng)絡(luò)編程12目錄網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)Socket基本編程技術(shù)Socket高級(jí)編程技術(shù)OSI模型與TCP/IP協(xié)議棧網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)3OSI七層協(xié)議功能物理層面向物理傳輸媒體,屏蔽媒體的不同鏈路層面向一條鏈路,成幀和無(wú)差錯(cuò)傳輸網(wǎng)絡(luò)層分配地址、面向多條鏈路、路由和流量控制傳輸層面向兩臺(tái)主機(jī)通信,處理可靠傳輸細(xì)節(jié),無(wú)差錯(cuò)、無(wú)失序傳輸會(huì)話層面向一次會(huì)話,協(xié)調(diào)雙方的交互、同步表示層面向通信內(nèi)容的表示,大家認(rèn)同的描述方式應(yīng)用層面向建立在通信基礎(chǔ)上的應(yīng)用,為應(yīng)用提供通信服務(wù)網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)4TCP協(xié)議特點(diǎn)面向連接的可靠傳輸端到端、建立/斷開(kāi)連接正確、順序傳送數(shù)據(jù)協(xié)議關(guān)注問(wèn)題IP數(shù)據(jù)報(bào)的丟失、重復(fù)、失序、延遲發(fā)送和接收速度的匹配系統(tǒng)重啟動(dòng),一方連接信息丟失網(wǎng)絡(luò)擁塞網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)5UDP協(xié)議特點(diǎn)無(wú)連接不需要在通信前建立連接不使用控制報(bào)文傳輸開(kāi)銷(xiāo)低面向報(bào)文不將報(bào)文分割,也不合并UDP報(bào)文大小直接影響網(wǎng)絡(luò)利用率過(guò)小造成報(bào)頭比率過(guò)大過(guò)大造成MTU分片盡力而為、任意交互一對(duì)一、一對(duì)多、多對(duì)一和多對(duì)多網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)6網(wǎng)絡(luò)服務(wù)的標(biāo)識(shí)TCP/UDP端口號(hào)作為服務(wù)器程序標(biāo)識(shí)服務(wù)器啟動(dòng)時(shí),首先在本地主機(jī)注冊(cè)所使用的TCP/UDP端口號(hào)客戶通過(guò)與服務(wù)器指定的TCP端口建立連接(或直接向服務(wù)器指定的UDP端口發(fā)送信息)來(lái)訪問(wèn)特定服務(wù)運(yùn)行服務(wù)器程序的主機(jī)收到信息后,將其轉(zhuǎn)交給注冊(cè)該端口的服務(wù)器程序處理網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)7客戶/服務(wù)器交互模型服務(wù)器程序被動(dòng)等待請(qǐng)求并做出響應(yīng)客戶程序主動(dòng)向服務(wù)器發(fā)出服務(wù)請(qǐng)求網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)8客戶/服務(wù)器程序特性對(duì)比網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)9服務(wù)器請(qǐng)求處理流程—循環(huán)服務(wù)器方案系統(tǒng)資源要求不高在處理一個(gè)請(qǐng)求時(shí)其他請(qǐng)求必須等待主要針對(duì)于面向無(wú)連接的客戶/服務(wù)器模型網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)10服務(wù)器請(qǐng)求處理流程—并發(fā)服務(wù)器方案系統(tǒng)資源要求較高實(shí)時(shí)性和靈活性是該方案的最大特點(diǎn)主要針對(duì)于面向連接的客戶/服務(wù)器模型網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)11Linux的網(wǎng)絡(luò)分層結(jié)構(gòu)BSDSocket是通用接口,支持各種網(wǎng)絡(luò)工作形式INETSocket支持包括TCP/IP協(xié)議在內(nèi)的Internet地址族網(wǎng)絡(luò)應(yīng)用BSDSocket層INETSocket層TCPUDPIPPPPSLIPSocketARP用戶數(shù)據(jù)界面接口界面協(xié)議分層網(wǎng)絡(luò)驅(qū)動(dòng)網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)12目錄網(wǎng)絡(luò)通信協(xié)議基礎(chǔ)Socket基本編程技術(shù)Socket高級(jí)編程技術(shù)13socket基本概念Socket接口是應(yīng)用程序與TCP/IP協(xié)議棧的接口定義一組函數(shù)/例程,支持TCP/IP網(wǎng)絡(luò)應(yīng)用程序開(kāi)發(fā)與數(shù)據(jù)通信相關(guān)的系統(tǒng)調(diào)用是read()/write()是一種文件描述符一個(gè)套接字描述一個(gè)通信連接的一端兩個(gè)通信程序中各自有一個(gè)套接字來(lái)描述自己的Socket不是TCP/IP標(biāo)準(zhǔn)的組成部分,但已成為事實(shí)上的工業(yè)標(biāo)準(zhǔn)UNIX系列系統(tǒng)提供SocketWindows系列、Macintosh系列、Solaris等亦提供網(wǎng)絡(luò)編程協(xié)議基礎(chǔ)14Socket端到端通信的形式形式(IP,PORT)網(wǎng)絡(luò)進(jìn)程標(biāo)識(shí)<協(xié)議,本地地址,本地端口>網(wǎng)間通信標(biāo)識(shí)<協(xié)議,本地地址,本地端口,遠(yuǎn)程地址,遠(yuǎn)程端口>端口分類(lèi)公認(rèn)端口小于256的端口作為保留端口注冊(cè)端口動(dòng)態(tài)和/或私有端口Socket基本編程技術(shù)15基本socketAPIsocket()創(chuàng)建一個(gè)新的Socketclose()關(guān)閉一個(gè)Socketbind()將服務(wù)器(IP,Port)賦予Socketlisten()等待到來(lái)的客戶連接請(qǐng)求(TCP)accept()接受客戶連接請(qǐng)求并建立連接(TCP)connect()向服務(wù)器發(fā)出連接請(qǐng)求send()/recv()發(fā)送/接收數(shù)據(jù)Socket基本編程技術(shù)16字節(jié)順序字節(jié)順序大端模式(big
endian):高字節(jié)放到高地址上小端模式(little
endian):高字節(jié)放到低地址上主機(jī)字節(jié)順序(HBO,HostByteOrder)不同的機(jī)器HBO不相同,與CPU設(shè)計(jì)有關(guān)Motorola68k系列,HBO與NBO相同Intelx86系列,HBO與NBO相反網(wǎng)絡(luò)字節(jié)順序(NBO,NetworkByteOrder)使用統(tǒng)一的字節(jié)順序,避免兼容性問(wèn)題解決兼容性問(wèn)題途徑往網(wǎng)絡(luò)上發(fā)送前:轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)序從網(wǎng)絡(luò)接收數(shù)據(jù):轉(zhuǎn)換成主機(jī)字節(jié)序
Socket基本編程技術(shù)17字節(jié)順序轉(zhuǎn)換函數(shù)頭文件#include<netinet/in.h>函數(shù)原型uint32_thtonl(uint32_thostlong);把32位值從主機(jī)字節(jié)序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)序uint16_thtons(uint16_thostshort);把16位值從主機(jī)字節(jié)序轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)序uint32_tntohl(uint32_thostlong);把32位值從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換成主機(jī)字節(jié)序uint16_tntohs(uint16_thostshort);把16位值從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換成主機(jī)字節(jié)序說(shuō)明h代表host,n代表networks代表short,l代表longSocket基本編程技術(shù)18socket()函數(shù)功能創(chuàng)建一個(gè)套接字#include<sys/socket.h>函數(shù)原型intsocket(intdomain,inttype,intprotocol);參數(shù)說(shuō)明domain:通信協(xié)議族,即地址族type:套接字類(lèi)型protocol:通信協(xié)議常設(shè)置為0,由內(nèi)核根據(jù)指定的類(lèi)型和協(xié)議族使用默認(rèn)的協(xié)議返回值成功時(shí),返回一個(gè)大于等于0的文件描述符失敗時(shí),返回一個(gè)小于0的值Socket基本編程技術(shù)19Linux支持的協(xié)議和地址族Socket基本編程技術(shù)20套接字類(lèi)型流套接字(SOCK_STREAM)可靠的、面向連接的通信使用TCP協(xié)議數(shù)據(jù)報(bào)套接字(SOCK_DGRAM)無(wú)連接服務(wù)使用UDP協(xié)議原始套接字(SOCK_RAW)允許對(duì)底層協(xié)議(如IP、ICMP)直接訪問(wèn)Socket基本編程技術(shù)21socket()函數(shù)代碼框架intmain(){
……
intsockfd;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror(“socket”);
exit(1);
}
……}Socket基本編程技術(shù)22套接字選項(xiàng)函數(shù)原型int
getsockopt(int
sockfd,int
level,int
optname,void
*optval,socklen_t
*optlen)int
setsockopt(int
sockfd,int
level,int
optname,const
void
*optval,socklen_t
*optlen)功能控制套接字行為,如修改緩沖區(qū)大小、傳輸方式等參數(shù)說(shuō)明level:指定控制套接字的層次SOL_SOCKET:通用套接字選項(xiàng)IPPROTO_IP:IP選項(xiàng)IPPROTO_TCP:TCP選項(xiàng)
optname:指定控制方式(選項(xiàng)名稱(chēng))optval:獲得/設(shè)置套接字選項(xiàng)值Socket基本編程技術(shù)23
SOL_SOCKET參數(shù)選項(xiàng) SO_BROADCAST 允許發(fā)送廣播數(shù)據(jù)
int
SO_DEBUG
允許調(diào)試
int
SO_DONTROUTE
不查找路由
int
SO_ERROR
獲得套接字錯(cuò)誤
int
SO_KEEPALIVE
保持連接
int
SO_LINGER
延遲關(guān)閉連接
struct
linger
SO_OOBINLINE
帶外數(shù)據(jù)放入正常數(shù)據(jù)流
int
SO_RCVBUF
接收緩沖區(qū)大小
int
SO_SNDBUF
發(fā)送緩沖區(qū)大小
int
SO_RCVLOWAT
接收緩沖區(qū)下限
int
SO_SNDLOWAT
發(fā)送緩沖區(qū)下限
int
SO_RCVTIMEO
接收超時(shí)
struct
timeval
SO_SNDTIMEO
發(fā)送超時(shí)
struct
timeval
SO_REUSERADDR
允許重用本地地址和端口
int
SO_TYPE
獲得套接字類(lèi)型
int
SO_BSDCOMPAT
與BSD系統(tǒng)兼容
int
Socket基本編程技術(shù)24IPPROTO_IP與IPPRO_TCP參數(shù)選項(xiàng)IPPROTO_IPIP_HDRINCL在數(shù)據(jù)包中包含IP首部IP_OPTINOSIP首部選項(xiàng)IP_TOS服務(wù)類(lèi)型IP_TTL生存時(shí)間IPPRO_TCPTCP_MAXSEGTCP最大數(shù)據(jù)段的大小TCP_NODELAY不使用Nagle算法
Socket基本編程技術(shù)25套接字選項(xiàng)示例更改發(fā)送/接收緩沖區(qū)大小接收緩沖區(qū)
intnRecvBuf=32*1024;
//設(shè)置為32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(constchar*)&nRecvBuf,sizeof(int));發(fā)送緩沖區(qū)
intnSendBuf=32*1024;//設(shè)置為32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(constchar*)&nSendBuf,sizeof(int));說(shuō)明對(duì)于客戶,SO_RCVBUF選項(xiàng)必須在connect之前設(shè)置對(duì)于服務(wù)器,SO_RCVBUF選項(xiàng)必須在listen前設(shè)置Socket基本編程技術(shù)26bind()函數(shù)功能將套接字地址與所創(chuàng)建的套接字號(hào)聯(lián)系起來(lái)客戶端如果只想使用connect(),則無(wú)須使用該函數(shù)#include<sys/socket.h>函數(shù)原型intbind(intsockfd,structsockaddr*my_addr,socklen_taddrlen);參數(shù)說(shuō)明sockfd:調(diào)用socket返回的文件描述符my_addr:保存地址信息(IP地址和端口)addrlen:設(shè)置為sizeof(structsockaddr)返回值成功時(shí),返回0失敗時(shí),返回-1Socket基本編程技術(shù)27sockaddr結(jié)構(gòu)定義功能保存socket信息結(jié)構(gòu)structsockaddr{unsignedshortsa_family;/*地址族,AF_xxx*/
charsa_data[14];/*協(xié)議地址*/};說(shuō)明sa_family一般為AF_INET(表示TCP/IP)sa_data包含socket的IP地址和端口號(hào)/include/linux/socket.hSocket基本編程技術(shù)28sockaddr_in結(jié)構(gòu)定義功能sockaddr的另一種表示形式結(jié)構(gòu)structsockaddr_in{
shortintsin_family;/*地址族*/
unsignedshortintsin_port;/*端口號(hào)*/
structin_addrsin_addr;/*IP地址*/
unsignedcharsin_zero[8];/*填充0,保持與structsockaddr等長(zhǎng)*/};說(shuō)明sin_zero用于將sockaddr_in結(jié)構(gòu)填充到與structsockaddr等長(zhǎng),可用bzero()或memset()函數(shù)將其置為0當(dāng)sin_port=0時(shí),系統(tǒng)隨機(jī)選擇一個(gè)未被使用的端口號(hào)當(dāng)sin_addr=INADDR_ANY時(shí),表示填入本機(jī)IP地址指向sockaddr_in的指針和指向sockaddr的指針可相互轉(zhuǎn)換structin_addr{__u32s_addr;};Socket基本編程技術(shù)29bind()函數(shù)示例 #include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#defineMYPORT3490
intmain(){
intsockfd;
structsockaddr_inmy_addr;
sockfd=socket(AF_INET,SOCK_STREAM,0);
my_addr.sin_family
=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr=inet_addr("132.241.5.10");
bind(sockfd,(structsockaddr*)&my_addr,sizeof(struct
sockaddr));…….}
Socket基本編程技術(shù)30connect()函數(shù)功能建立套接字連接#include<sys/socket.h>函數(shù)原型intconnect(intsockfd,conststructsockaddr*serv_addr,socklen_taddrlen);參數(shù)說(shuō)明sockfd:調(diào)用socket返回的文件描述符serv_addr:遠(yuǎn)程主機(jī)IP地址和端口addrlen:設(shè)置為sizeof(structsockaddr)返回值成功時(shí),返回0失敗時(shí),返回-1Socket基本編程技術(shù)31connect()函數(shù)示例 #include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#defineDEST_IP"132.241.5.10"
#defineDEST_PORT23
intmain(){
intsockfd;
structsockaddr_indest_addr;
sockfd=socket(AF_INET,SOCK_STREAM,0);
dest_addr.sin_family=AF_INET;
dest_addr.sin_port=htons(DEST_PORT);
dest_addr.sin_addr.s_addr=inet_addr(DEST_IP);
connect(sockfd,(structsockaddr*)&dest_addr,
sizeof(structsockaddr));
Socket基本編程技術(shù)32listen()函數(shù)功能用于面向連接服務(wù)器,表明愿意接收連接#include<sys/socket.h>函數(shù)原型intlisten(intsockfd,intbacklog);參數(shù)說(shuō)明sockfd:調(diào)用socket返回的文件描述符backlog:accept()應(yīng)答之前,允許在進(jìn)入隊(duì)列中等待的連接數(shù)目,出錯(cuò)時(shí)返回-1返回值成功時(shí),返回0失敗時(shí),返回-1說(shuō)明在使用listen()之前,需要調(diào)用bind()綁定到需要的端口,否則系統(tǒng)內(nèi)核將會(huì)監(jiān)聽(tīng)一個(gè)隨機(jī)端口socket();
bind();
listen();Socket基本編程技術(shù)33accept()函數(shù)功能建立套接字連接,處理單個(gè)連接請(qǐng)求(如發(fā)送/接收數(shù)據(jù))#include<sys/socket.h>函數(shù)原型intaccept(intsockfd,structvoid*addr,socklen_t*addrlen);參數(shù)說(shuō)明sockfd:正在監(jiān)聽(tīng)端口的套接字文件描述符addr:指向本地?cái)?shù)據(jù)結(jié)構(gòu)sockaddr_in的指針調(diào)用connect()的信息將存儲(chǔ)在該結(jié)構(gòu)中addrlen:設(shè)置為sizeof(structsockaddr_in)返回值成功時(shí),返回一個(gè)socket端口失敗時(shí),返回-1Socket基本編程技術(shù)34accept()函數(shù)intmain(){ intsockfd,client_fd; structsockaddr_in
remote_addr;
/*客戶端地址信息*/ …… while(1){ sin_size=sizeof(structsockaddr_in); if((client_fd=accept(sockfd,(structsockaddr*)
&remote_addr,&sin_size))==-1){ perror("accept");continue; } printf("from%s\n",inet_ntoa(remote_addr.sin_addr)); …… } ……}
Socket基本編程技術(shù)35send()函數(shù)功能通過(guò)socket發(fā)送數(shù)據(jù)#include<sys/types.h>#include<sys/socket.h>函數(shù)原型ssize_tsend(intsockfd,constvoid*buf,size_tlen,intflags);參數(shù)說(shuō)明sockfd:發(fā)送數(shù)據(jù)的套接字描述符msg:指向發(fā)送數(shù)據(jù)的指針len:數(shù)據(jù)長(zhǎng)度f(wàn)lags:一般設(shè)置為0返回值成功時(shí),返回實(shí)際發(fā)送的數(shù)據(jù)的字節(jié)數(shù)失敗時(shí),返回-1Socket基本編程技術(shù)36recv()函數(shù)功能通過(guò)socket接收數(shù)據(jù)#include<sys/types.h>#include<sys/socket.h>函數(shù)原型ssize_trecv(intsockfd,void*buf,size_tlen,intflags);參數(shù)說(shuō)明sockfd:要讀的SOCKET描述符buf:要讀的信息的緩沖區(qū)len:緩沖的最大長(zhǎng)度f(wàn)lags:一般設(shè)置為0返回值成功時(shí),返回實(shí)際接收到的數(shù)據(jù)的字節(jié)數(shù)失敗時(shí),返回-1Socket基本編程技術(shù)37send()/recv()中的flags說(shuō)明MSG_DONTROUTEsend()的使用標(biāo)志,不查找路由表,表示目的主機(jī)在本地網(wǎng)絡(luò)MSG_OOB接收或者發(fā)送帶外數(shù)據(jù)MSG_PEEKrecv()的使用標(biāo)志,查看數(shù)據(jù)但不從系統(tǒng)緩沖區(qū)移走數(shù)據(jù)MSG_WAITALLrecv()的使用標(biāo)志,等待所有數(shù)據(jù),阻塞式接收,直到滿足條件或發(fā)生錯(cuò)誤讀到指定字節(jié)時(shí),正常返回,返回值等于len讀到文件尾,正常返回,返回值小于len操作錯(cuò)誤時(shí),返回-1Socket基本編程技術(shù)38帶外數(shù)據(jù)傳輸層協(xié)議使用帶外數(shù)據(jù)(out-of-band,OOB)來(lái)發(fā)送一些重要數(shù)據(jù)若通信一方有重要數(shù)據(jù)需要通知對(duì)方時(shí),協(xié)議能將這些數(shù)據(jù)快速地發(fā)送到對(duì)方為發(fā)送這些數(shù)據(jù),協(xié)議一般不使用與普通數(shù)據(jù)相同的通道,而是使用另外的通道Linux套接字機(jī)制支持低層協(xié)議發(fā)送/接收帶外數(shù)據(jù),但TCP協(xié)議沒(méi)有真正意義上的帶外數(shù)據(jù)為發(fā)送重要協(xié)議,TCP提供緊急模式機(jī)制TCP協(xié)議在數(shù)據(jù)段中設(shè)置URG位,表示進(jìn)入緊急模式接收方可以對(duì)緊急模式采取特殊的處理這種方式數(shù)據(jù)不容易被阻塞,且可通過(guò)在服務(wù)器端程序里捕捉SIGURG信號(hào)來(lái)及時(shí)接收數(shù)據(jù)TCP協(xié)議每次只能發(fā)送和接收一個(gè)字節(jié)帶外數(shù)據(jù)Socket基本編程技術(shù)39TCP發(fā)送帶外數(shù)據(jù)的處理機(jī)制TCP總將最后一個(gè)字節(jié)當(dāng)作OOB數(shù)據(jù),其余當(dāng)作普通字節(jié)不管通過(guò)帶MSG_OOB標(biāo)志的sendXXXX()函數(shù)發(fā)送多少字節(jié)OOB數(shù)據(jù),發(fā)送端只將最后一個(gè)字節(jié)當(dāng)作OOB數(shù)據(jù)接收端也只能收到一個(gè)字節(jié)的OOB數(shù)據(jù)舉例:send(sendfd,"ABC",3,MSG_OOB)TCP將緊急模式URG置位緊急指針定位第三個(gè)字節(jié)(“C”)前兩個(gè)字節(jié)("AB")當(dāng)作普通字節(jié)發(fā)送
Socket基本編程技術(shù)40TCP接收帶外數(shù)據(jù)的處理機(jī)制TCP提供兩種處理模式非OOBINLINE模式:套接字的默認(rèn)模式將OOB字節(jié)與普通字節(jié)分開(kāi)存放,OOB字節(jié)存放在一個(gè)OOB緩沖區(qū)中OOBINLINE模式:OOB字節(jié)和普通字節(jié)一起存放recvXXXX函數(shù)在MSG_OOB模式下,將在OOB緩沖區(qū)中尋找數(shù)據(jù)如果發(fā)送端沒(méi)發(fā)送OOB字節(jié),它返回錯(cuò)誤如果發(fā)送端發(fā)送了OOB字節(jié)對(duì)于非OOBINLINE模式,返回1字節(jié)的OOB數(shù)據(jù)對(duì)于OOBINLINE模式,返回錯(cuò)誤,因?yàn)镺OB字節(jié)沒(méi)有放到OOB緩沖區(qū)中
Socket基本編程技術(shù)41sendto()函數(shù)功能用于數(shù)據(jù)報(bào)套接字的通信#include<sys/types.h>#include<sys/socket.h>函數(shù)原型intsendto(intsockfd,constvoid*msg,intlen,unsignedintflags,conststructsockaddr*to,inttolen);參數(shù)說(shuō)明to:目地機(jī)的IP地址和端口號(hào)信息tolen:常被賦值為sizeof(structsockaddr)返回值成功時(shí),返回實(shí)際發(fā)送的數(shù)據(jù)的字節(jié)數(shù)失敗時(shí),返回-1Socket基本編程技術(shù)42recvfrom()函數(shù)功能用于數(shù)據(jù)報(bào)套接字的通信#include<sys/types.h>#include<sys/socket.h>函數(shù)原型intrecvfrom(intsockfd,void*buf,intlen,unsignedintflags,structsockaddr*from,int*fromlen);參數(shù)說(shuō)明from:保存源機(jī)的IP地址及端口號(hào)fromlen:常常被賦值為sizeof(structsockaddr)返回值成功時(shí),返回實(shí)際接收到的數(shù)據(jù)的字節(jié)數(shù)失敗時(shí),返回-1Socket基本編程技術(shù)43write()函數(shù)函數(shù)原型ssize_t
write(int
fd,const
void
*buf,size_t
nbytes)功能將buf中的nbytes字節(jié)內(nèi)容寫(xiě)入文件描述符fd返回值成功時(shí)返回寫(xiě)的字節(jié)數(shù)失敗時(shí)返回-1,并設(shè)置errno變量說(shuō)明返回值大于0,表示寫(xiě)入部分或全部數(shù)據(jù)返回值小于0,表示出現(xiàn)錯(cuò)誤如果錯(cuò)誤為EINTR,表示在寫(xiě)的時(shí)候出現(xiàn)中斷錯(cuò)誤如果為EPIPE,表示網(wǎng)絡(luò)連接出現(xiàn)問(wèn)題Socket基本編程技術(shù)44基于write()函數(shù)的socket寫(xiě)實(shí)現(xiàn)Socket基本編程技術(shù)45read()函數(shù)函數(shù)原型ssize_t
read(int
fd,void
*buf,size_t
nbyte)功能從fd中讀取內(nèi)容返回值讀成功時(shí),返回實(shí)際所讀的字節(jié)數(shù)如果返回的值是0
表示已經(jīng)讀到文件的結(jié)束,出錯(cuò)時(shí),返回值小于0如果錯(cuò)誤為EINTR,說(shuō)明讀是由中斷引起的如果是ECONNREST表示網(wǎng)絡(luò)連接出了問(wèn)題Socket基本編程技術(shù)46基于read()函數(shù)的socket讀實(shí)現(xiàn)Socket基本編程技術(shù)47close()/shutdown()函數(shù)功能關(guān)閉通訊函數(shù)原型intclose(intsockfd);intshutdown(intsockfd,inthow);參數(shù)說(shuō)明sockfd:要關(guān)閉的套接字描述符how:0:不允許接收1:不允許發(fā)送2:不允許發(fā)送和接收(和close()一樣)返回值成功時(shí),返回0失敗時(shí),返回-1Socket基本編程技術(shù)48getpeername()/gethostname()函數(shù)intgetpeername(intsockfd,structsockaddr*addr,int*addrlen);獲取socket連接另一端的主機(jī)信息sockfd:是連接的數(shù)據(jù)流套接口文件描述符addr:保存另一端主機(jī)信息addrlen:設(shè)置為sizeof(structsockaddr)intgethostname(char*hostname,size_tsize);返回程序正在運(yùn)行的計(jì)算機(jī)的名字返回值如果成功,返回0如果失敗,返回-1
Socket基本編程技術(shù)49IP地址與域名的獲取函數(shù)原型#include<netdb.h>structhostent*gethostbyname(constchar*name);structhostent*gethostbyaddr(constchar*addr,size_tlen,inttype);structhostent{char*h_name;/*主機(jī)的正式名稱(chēng)*/char**h_aliases;/*主機(jī)的別名*/inth_addrtype;/*主機(jī)的地址類(lèi)型
AF_INET*/inth_length;/*主機(jī)的地址長(zhǎng)度
對(duì)于IP4
是4字節(jié)32位*/char**h_addr_list;/*主機(jī)的IP地址列表*/#defineh_addrh_addr_list[0]/*主機(jī)的第一個(gè)IP地址*/};Socket基本編程技術(shù)50字符串的IP與32的IP的轉(zhuǎn)換說(shuō)明
網(wǎng)絡(luò)上的IP都是數(shù)字加點(diǎn)(192.168.0.1)構(gòu)成structin_addr結(jié)構(gòu)使用32位的IP,如IP(C0A80001)是192.168.0.1函數(shù)原型intinet_aton(constchar*cp,structin_addr*inp)將a.b.c.d的IP轉(zhuǎn)換為32位的IP,存儲(chǔ)在inp指針里面char*inet_ntoa(structin_addrin)將32位IP轉(zhuǎn)換為a.b.c.d的格式說(shuō)明a代表ascii,n代表networkSocket基本編程技術(shù)51面向連接的socket通信流程客戶端s=socket(),建立流式套接字,返回套接字號(hào)sconnect(s),將套接字s與遠(yuǎn)程主機(jī)連接recv(s)/send(s),在套接字s上讀/寫(xiě)數(shù)據(jù)至完成交換close(s),關(guān)閉套接字s,結(jié)束TCP對(duì)話s=socket(),建立流式套接字,返回套接字號(hào)sbind(s),套接字s與本地地址相連listen(s),通知TCP服務(wù)器準(zhǔn)備好接收連接ns=accept(s),接收連接,等待客戶端的連接…建立連接,accept()返回,得到新的套接字nsclose(ns),關(guān)閉套接字nsrecv(ns)/send(ns),在套接字ns上讀/寫(xiě)數(shù)據(jù)至完成交換服務(wù)器端close(s),關(guān)閉最初套接字s,服務(wù)結(jié)束Socket基本編程技術(shù)52面向連接socket通信流程服務(wù)器程序作用初始化服務(wù)器程序持續(xù)監(jiān)聽(tīng)一個(gè)固定的端口收到客戶的連接后建立一個(gè)socket連接與客戶進(jìn)行通信和信息處理接收客戶通過(guò)socket連接發(fā)送來(lái)的數(shù)據(jù),創(chuàng)建一個(gè)新的socket,通過(guò)socket連接與客戶通信,進(jìn)行相應(yīng)處理,并返回處理結(jié)果通信結(jié)束后中斷與客戶的連接(關(guān)閉socket)Socket基本編程技術(shù)53面向連接的socket通信流程客戶程序作用初始化客戶程序連接到某個(gè)服務(wù)器上,建立socket連接與服務(wù)器進(jìn)行通信和信息處理接收服務(wù)器通過(guò)socket連接發(fā)送來(lái)的數(shù)據(jù),進(jìn)行相應(yīng)處理通過(guò)socket連接向服務(wù)器發(fā)送請(qǐng)求信息通信結(jié)束后中斷與客戶的連接Socket基本編程技術(shù)54面向連接socket通信示例—服務(wù)器程序Socket基本編程技術(shù)55面向連接socket通信示例—服務(wù)器程序Socket基本編程技術(shù)56面向連接socket通信示例—服務(wù)器程序Socket基本編程技術(shù)57面向連接socket通信示例—服務(wù)器程序Socket基本編程技術(shù)58面向連接socket通信示例—客戶程序Socket基本編程技術(shù)59面向連接socket通信示例—客戶程序Socket基本編程技術(shù)60面向連接socket通信示例—客戶程序Socket基本編程技術(shù)61面向無(wú)連接socket通信流程客戶端s=socket(),建立數(shù)據(jù)報(bào)套接字,返回套接字號(hào)sbind(s),將套接字s與本地主機(jī)連接(可選)recvfrom(s)/sendto(s),在套接字s上讀/寫(xiě)數(shù)據(jù)至完成交換close(s),關(guān)閉套接字s,結(jié)束UDP對(duì)話bind(s),套接字s與本地地址相連s=socket(),建立數(shù)據(jù)報(bào)套接字,返回套接字號(hào)srecvfrom(s)/sendto(s),在套接字s上讀/寫(xiě)數(shù)據(jù)至完成交換close(s),關(guān)閉套接字s服務(wù)器端Socket基本編程技術(shù)62面向無(wú)連接通信適用場(chǎng)景面向數(shù)據(jù)報(bào)網(wǎng)絡(luò)數(shù)據(jù)大多為短消息擁有大量客戶對(duì)數(shù)據(jù)安全性無(wú)特殊要求網(wǎng)絡(luò)負(fù)擔(dān)非常重,但對(duì)響應(yīng)速度要求高Socket基本編程技術(shù)63面向無(wú)連接socket通信示例—公共函數(shù)Socket基本編程技術(shù)64面向無(wú)連接socket通信示例—公共函數(shù)Socket基本編程技術(shù)65面向無(wú)連接socket通信示例—服務(wù)程序Socket基本編程技術(shù)66面向無(wú)連接socket通信示例—服務(wù)程序Socket基本編程技術(shù)67面向無(wú)連接socket通信示例—服務(wù)器程序Socket基本編程技術(shù)68面向無(wú)連接socket通信示例—客戶程序Socket基本編程技術(shù)69面向無(wú)連接socket通信示例—客戶程序Socket基本編程技術(shù)70服務(wù)器請(qǐng)求處理流程—循環(huán)服務(wù)器方案UDP實(shí)現(xiàn)框架沒(méi)有一個(gè)客戶端可以一直占用服務(wù)端只要處理過(guò)程不是死循環(huán),則服務(wù)器對(duì)于每一個(gè)客戶機(jī)的請(qǐng)求總是能夠滿足
socket(...);
bind(...);
while(1)
{
recvfrom(...);
process(...);
sendto(...);
}
Socket基本編程技術(shù)71服務(wù)器請(qǐng)求處理流程—循環(huán)服務(wù)器方案TCP實(shí)現(xiàn)框架每次接受一個(gè)客戶端連接完成某客戶所有請(qǐng)求后,斷開(kāi)連接
socket(...);
bind(...);
listen(...);
while(1){
accept(...);
{
recv(...);
process(...);
send(...);
}
close(...);
}Socket基本編程技術(shù)72服務(wù)器請(qǐng)求處理流程—并發(fā)服務(wù)器方案TCP實(shí)現(xiàn)框架
s=socket(...);
bind(s,...);
listen(s,...);
while(1)
{
ns=accept(s,...);
if(fork(..)==0)
{
recv(ns,...);
process(...);
send(ns,...);
close(ns);}
}
}
Socket基本編程技術(shù)73多線程客戶/服務(wù)器示例—線程實(shí)現(xiàn)功能描述客戶端使用線程向服務(wù)器發(fā)送從標(biāo)準(zhǔn)輸入得到的字符在主線程中將從服務(wù)器端返回的字符顯示到標(biāo)準(zhǔn)輸出服務(wù)器端將客戶端發(fā)來(lái)的數(shù)據(jù)原樣返回給客戶端,每一個(gè)客戶在服務(wù)器上對(duì)應(yīng)一個(gè)線程Socket基本編程技術(shù)74多線程客戶/服務(wù)器示例—線程實(shí)現(xiàn)公共文件Socket基本編程技術(shù)75多線程客戶/服務(wù)器示例—線程實(shí)現(xiàn)客戶端Socket基本編程技術(shù)76多線程客戶/服務(wù)器示例—線程實(shí)現(xiàn)客戶端Socket基本編程技術(shù)Sockfd未實(shí)例化?。?!77多線程客戶/服務(wù)器示例—線程實(shí)現(xiàn)服務(wù)器端Socket基本編程技術(shù)pthread_detach(thread_id)(非阻塞,可立即返回)這將該子線程的狀態(tài)設(shè)置為detached,則該線程運(yùn)行結(jié)束后會(huì)自動(dòng)釋放所有資源。78多線程客戶/服務(wù)器示例—線程實(shí)現(xiàn)服務(wù)器端Socket基本編程技術(shù)79目錄網(wǎng)絡(luò)通信協(xié)議基礎(chǔ)Socket基本編程技術(shù)Socket高級(jí)編程技術(shù)80阻塞式I/O可能造成阻塞的函數(shù)有:connect()、accept()、讀寫(xiě)函數(shù)、select()、poll()、gethostbyname()等Socket高級(jí)編程技術(shù)81非阻塞式I/O調(diào)用可能造成阻塞的函數(shù)時(shí),若發(fā)生阻塞,函數(shù)返回-1并將errno設(shè)置為EAGAIN或EWOULDBLOCK,程序可繼續(xù)向下運(yùn)行非阻塞模式需要程序不斷檢查各個(gè)可能阻塞的函數(shù)的狀態(tài)當(dāng)一個(gè)應(yīng)用程序使用了非阻塞模式的套接字,它需要使用一個(gè)循環(huán)來(lái)不停的測(cè)試是否一個(gè)文件描述符有數(shù)據(jù)可讀(稱(chēng)做p
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 建筑風(fēng)格二手房買(mǎi)賣(mài)合同
- 城市安全簡(jiǎn)易工程施工合同
- 2025個(gè)人銷(xiāo)售合同模板
- 體育館施工合同模板
- 潛水俱樂(lè)部洗車(chē)場(chǎng)租賃合同
- 郵政服務(wù)設(shè)備承包協(xié)議
- 2025安置房購(gòu)房合同樣書(shū)
- 沙灘排球場(chǎng)景觀護(hù)欄安裝協(xié)議
- 陶瓷店裝修施工合同
- 勞動(dòng)合同解除后的經(jīng)濟(jì)補(bǔ)償計(jì)算
- 文學(xué)創(chuàng)造的奧妙智慧樹(shù)知到期末考試答案章節(jié)答案2024年山東師范大學(xué)
- 涯規(guī)未來(lái)智慧樹(shù)知到期末考試答案章節(jié)答案2024年云南師范大學(xué)
- 青少版新概念3B-U21市公開(kāi)課一等獎(jiǎng)省賽課微課金獎(jiǎng)?wù)n件
- 儲(chǔ)能業(yè)務(wù)培訓(xùn)
- 2024屆新高考物理沖刺復(fù)習(xí):“正則動(dòng)量”解決帶電粒子在磁場(chǎng)中的運(yùn)動(dòng)問(wèn)題
- 《印學(xué)話西泠》參考課件
- 普通話智慧樹(shù)知到期末考試答案2024年
- (2024年)大學(xué)生考風(fēng)考紀(jì)主題班會(huì)課件
- 科技創(chuàng)新專(zhuān)項(xiàng)規(guī)劃編制工作方案
- 2024年國(guó)家糧食和物資儲(chǔ)備局直屬事業(yè)單位招聘筆試參考題庫(kù)附帶答案詳解
- 股東撤資協(xié)議
評(píng)論
0/150
提交評(píng)論