版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Socket編程
培訓(xùn)思路:
■Socket是什么玩意
■咋使用和設(shè)計(jì)Socket進(jìn)行通信
socket概述
linux中的網(wǎng)絡(luò)編程通過(guò)socket接口實(shí)現(xiàn)。Socket
既是一種特殊的10,它也是一種文件描述符。
一個(gè)完整的Socket都有一個(gè)相關(guān)描述{協(xié)議,
本地地址,本地端口,遠(yuǎn)程地址,遠(yuǎn)程端口};
每一個(gè)Socket有一個(gè)本地的唯一Socket號(hào),
由操作系統(tǒng)分配。
文件描述符
■內(nèi)核(kernel)利用文件描述符(file
descriptor)來(lái)訪問(wèn)文件。文件描述符是
非負(fù)整數(shù)。打開(kāi)現(xiàn)存文件或新建文件時(shí),
內(nèi)核會(huì)返回一個(gè)文件描述符。讀寫(xiě)文件
也需要使用文件描述符來(lái)指定待讀寫(xiě)的
文件
常見(jiàn)套接字有二種類型:
流式套接字(SOCK_STREAM)
■流式的套接字可口提供可靠的、面向連接的
通訊流。它使用了TCP協(xié)議。TCP保證了數(shù)據(jù)
傳輸?shù)恼_性和順序性。
■數(shù)據(jù)報(bào)套接字(SOCK_DGRAM)
■數(shù)據(jù)報(bào)套接字定義?一種無(wú)連接的服務(wù),數(shù)
據(jù)通過(guò)相互獨(dú)立的報(bào)文進(jìn)行傳輸,是無(wú)序的,
并且不保證可靠,無(wú)差錯(cuò)。使用數(shù)據(jù)報(bào)協(xié)議
UDP協(xié)議。
如何使用和設(shè)計(jì)Socket進(jìn)行通信
■Socket的建立、配置、連接、數(shù)據(jù)傳輸、
結(jié)束
■以上的主要步驟由socket函數(shù)實(shí)現(xiàn)
Socket函數(shù)介紹
需要用到的頭文件
■數(shù)據(jù)類型:ttinclude<sys/types.h>
■函數(shù)定義:ttinclude<sys/socket.h>
Socket常用函數(shù)列表
■網(wǎng)絡(luò)連接函數(shù)
■獲取/設(shè)置socket的參數(shù)或信息
■轉(zhuǎn)換函數(shù)
網(wǎng)絡(luò)連接函數(shù)
■socket
■bind
■connect
■listen
■accept
■select
■recv,recvfrom
■send,sendto
■close,shutdown
獲取/設(shè)置socket的參數(shù)或信息
■gethostbyaddr,gethostbyname
■gethostname
■getpeername
■getprotobyname,getprotobynumber
■getservbyname,getservbyport
■getsockname
■getsockopt,setsockopt
■ioctl
轉(zhuǎn)換函數(shù)
■IP地址轉(zhuǎn)換
■inet_addr()
■inet_ntoa()
-字節(jié)順序轉(zhuǎn)換
■htonsO-"HosttoNetworkShort"
■htonl()-"HosttoNetworkLong"
■ntohs()-"NetworktoHostShort"
■ntohl()-"NetworktoHostLong"
數(shù)據(jù)結(jié)構(gòu):sockaddr
structsockaddr{
unsignedshortsa_family;/*addressfamily,
AF_xxx*/
charsa_data[14];/*14bytesof
protocoladdress
*/
);
此數(shù)據(jù)結(jié)構(gòu)用做bind、connect、recvfrom>
sendto等函數(shù)的參數(shù),指明地址信息
數(shù)據(jù)結(jié)構(gòu):sockaddrjn
structsockaddrjn{
shortintsin_family;/*Addressfamily*/
unsignedshortintsin_port;/*Portnumber*/
structinaddrsinaddr;/*Internetaddress*/
unsignedcharsin_zero[8];/*Samesizeas
structsockaddr*/
);
該結(jié)構(gòu)與sockaddr兼容,供用戶填入?yún)?shù)
數(shù)據(jù)結(jié)構(gòu):inaddr
structin_addr{
unsignedlongs_addr;
這個(gè)數(shù)據(jù)結(jié)構(gòu)是由于歷史原因保留下來(lái)的,主
要用作與以前的格式兼容。
structsockaddrjnmy_addr;
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(3490);/*short,
NBO*/
my_addr.sin_addr.s_addr=inet_addr("0");
bzero(&(my_addr,sin_zero)78);
注意:sin_addr.s_addr填本機(jī)IP,如果此項(xiàng)填
INADDR_ANY時(shí),表示自動(dòng)取本機(jī)IP填入該項(xiàng)(僅
用于Server)
函數(shù)簡(jiǎn)介:socket
■Socket描述符與Linux中的文件描述符類似,也
是一個(gè)int型的變量
-函數(shù)調(diào)用:
■intsocket(intdomain,inttype,intprotocol);
-函數(shù)返回Socket描述符,返回-1表示出錯(cuò)
■domain參數(shù)只能取AF」NET,protocol參數(shù)一般取0
■應(yīng)用示例:
-TCP:sockfd=socket(AF_INETzSOCK_STREAMzO);
-UDP:sockfd=socket(AF_INET,SOCK_DGRAMzO);
函數(shù)簡(jiǎn)介:bind
■作為Server程序,需要與一個(gè)端口綁定
intbind(intsockfd,structsockaddr*my_addr,
intaddrlen);
bind函數(shù)返回-1表示出錯(cuò),最常見(jiàn)的錯(cuò)誤是該
端口已經(jīng)被其他程序綁定。
需要注意的一點(diǎn):在Linux系統(tǒng)中,1024以下的
端口只有擁有root權(quán)限的程序才能綁定
函數(shù)簡(jiǎn)介:listen
■開(kāi)始監(jiān)聽(tīng)已經(jīng)綁定的端口
-需要在此前調(diào)用bind。函數(shù),否則由系統(tǒng)指定一個(gè)
隨機(jī)的端口
■intlisten(intsockfd,intqueuejength);
■接收隊(duì)列
-一個(gè)新的Client的連接請(qǐng)求先被放在接收隊(duì)列中,
等待Server程序調(diào)用accept函數(shù)接受連接請(qǐng)求
■queue_length指的就是接收隊(duì)列的長(zhǎng)度
也就是在Server程序調(diào)用accept函數(shù)之前最大允許的連接請(qǐng)
求數(shù),多余的連接請(qǐng)求將被拒絕
函數(shù)簡(jiǎn)介:accept
■accept。函數(shù)將響應(yīng)連接請(qǐng)求,建立連接
■產(chǎn)生一個(gè)新的socket描述符來(lái)描述該連接
■這個(gè)連接用來(lái)與特定的Client交換信息
■intaccept(intsockfd,structsockaddr*addr,int
*addrlen);
■addr將在函數(shù)調(diào)用后被填入連接對(duì)方的地址
信息,如對(duì)方的IP、端口等。
■accept缺省是阻塞函數(shù),阻塞直到有連接請(qǐng)求
函數(shù)簡(jiǎn)介:connect
連接某個(gè)Server
intconnect(intsockfd,structsockaddr*servaddr,
intaddrlen);
■servaddr是事先填寫(xiě)好的結(jié)構(gòu),Server的IP和端口都
在該數(shù)據(jù)結(jié)構(gòu)中指定。
函數(shù)簡(jiǎn)介:recv
用于TCP協(xié)議中接收信息
intrecv(intsockfd,void*buf,intlen,intflags);
-buf,對(duì)向容納接收信息的緩沖區(qū)的指針
■len,緩沖區(qū)的大小
■flags,接收標(biāo)志
■函數(shù)返回實(shí)際接收的字節(jié)數(shù),返回-1表示出錯(cuò)
■recv缺省是阻塞函數(shù),直到接收到信息或出錯(cuò)
函數(shù)簡(jiǎn)介:send
用于TCP協(xié)議中發(fā)送信息
intsend(intsockfd,constvoid*msg,intlen,int
flags);
-msg,指向待發(fā)送信息的指針
-len,待發(fā)送的字節(jié)數(shù)
-flags,發(fā)送標(biāo)志
■函數(shù)返回已發(fā)送的字節(jié)數(shù),返回-1表示出錯(cuò)
■send缺省是阻塞函數(shù),直到發(fā)送完畢或出錯(cuò)
-注意:如果函數(shù)返回值與參數(shù)len不相等,則剩
余的未發(fā)送信息需要再次發(fā)送
函數(shù)簡(jiǎn)介:close
■關(guān)閉特定的socket連接
■調(diào)用函數(shù):intclose(intsockfd);
-關(guān)閉連接將中斷對(duì)該socket的讀寫(xiě)操作。
■關(guān)閉用于listen。函數(shù)的socket將禁止其
他Client的連接請(qǐng)求
函數(shù)簡(jiǎn)介:shutdown
■Shutdown。函數(shù)可以單方面的中斷連接,
即禁止某個(gè)方向的信息傳遞。
-函數(shù)調(diào)用
■intshutdown(intsockfd,inthow);
■參數(shù)how:
0-禁止接收信息
]-禁止發(fā)送信息
2-晶收和發(fā)il嬴被禁止,與dose()函數(shù)效果相同
■返回。表示調(diào)用成功,返回-1表示出錯(cuò)
函數(shù)簡(jiǎn)介:inetaddr,inet_ntoa
unsignedlonginet_addr(constchar*cp);
■inet_addr將一個(gè)點(diǎn)分十進(jìn)制IP地址字符串轉(zhuǎn)換
成3萬(wàn)位數(shù)字表示的IP地址
char*inet_ntoa(structin_addrin);
■inejntoa將一個(gè)32位數(shù)字表示的IP地址轉(zhuǎn)換
成點(diǎn)分十進(jìn)制IP地址字符串
這兩個(gè)函數(shù)互為反函數(shù)
TCP:基于連接流的網(wǎng)絡(luò)協(xié)議
■TCP相關(guān)的函數(shù)
■Server的例子
■Client的例子
■Server-Client結(jié)構(gòu)圖
TCP應(yīng)用舉例
Server部分
Server程序的作用
■程序初始化
■持續(xù)監(jiān)聽(tīng)一個(gè)固定的端口
■收到Client的連接后建立一個(gè)socket連接
■與Client進(jìn)行通信和信息處理
-接收Client通過(guò)socket連接發(fā)送來(lái)的數(shù)據(jù),
進(jìn)行相應(yīng)處理并返回處理結(jié)果,如BBS
Server
■通過(guò)socket連接向Client發(fā)送信息,
如TimeServer
■通信結(jié)束后中斷與Client的連接
一個(gè)簡(jiǎn)單的TCPServer
完整的Server程序不例
程序流程一
■取得socket描述符:
intsockfd;
sockfd=socket(AFJNET,SOCK_STREAM,
0);
程序流程二
■填寫(xiě)自身地址信息的sockaddr_in結(jié)構(gòu)
structsockaddrjnmy_addr;/*自身的地
址信息*/
my_addr.sin_family=AF_INET;
/*網(wǎng)絡(luò)字節(jié)順序*/
my_addr,sin_port=htons(MYPORT);
/*百動(dòng)填本機(jī)IP*/
my_addr.sin_addr.s_addr=INADDR_ANY;
/*其余部分置0*/
bzero(&(my_addr.sin_zero),8);
程序流程三
■綁定端口
bind(sockfd,(structsockaddr*)&my_addr,
sizeof(structsockaddr));
程序流程四
■監(jiān)聽(tīng)端口
#defineBACKLOG10
listen(sockfd,BACKLOG);
程序流程五
-接受連接請(qǐng)求
intnew_fd;/*數(shù)據(jù)端口*/
structsockaddrjntheir_addr;/*連接對(duì)方的
地址信息*/
intsinsize;
sin_size=sizeof(structsockaddrjn);
new_fd=accept(sockfd,(structsockaddr
*)&their_addr,&sin_size))
程序流程六
■產(chǎn)生新進(jìn)程(線程)處理讀寫(xiě)socket
if(!fork()){/*子進(jìn)程7
if(send(new_fd,"Hello,world!\n",14,0)==
-1)perror("sendn);
close(new_fd);
exit(0);
close(new_fd);
程序流程七
-轉(zhuǎn)程序流程五,繼續(xù)等待其他Client的連
接并處理
#include<stdio.h>
#ihclude<stdlib.h>
#iiclude<ermo.h>
#1Elude<string.h>
^wlude<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/wait.h>
#defineMYPORT3490/*監(jiān)聽(tīng)端口*/
#defineBACKLOG10/*listen的請(qǐng)求接收隊(duì)列長(zhǎng)度*/
voidmain()
(
intsockfd,newfd;/*監(jiān)聽(tīng)端口,數(shù)據(jù)端口*/
structsockaddrinmy_addr;/*自身的地址信息*/
structsockaddrintheiraddr;/*連接對(duì)方的地址信息*/
intsin_size;
if((sockfd=socket(AF_INET,SOCKSTREAM,0))==-1){
perror(nsocketn);
exit(l);
myaddr.sinfamily=AFINET;
myaddr.sin_port=htons(MYPORT);/*網(wǎng)絡(luò)字節(jié)順序*/
myaddr.sinaddr.saddr=INADDRANY;/*自動(dòng)填本機(jī)IP*/
bzero(&(my_addr.sin_zero),8);/*其余部分置0*/
if(bind(sockfd,(structsockaddr*)&my_addr,
sizeofifstructsockaddr))==-1){
perror(nbindn);
exit(l);
}
if(listen(sockfd,BACKLOG)==-1){
perror(nlistenu);
exit(l);
while(l){/*主循環(huán)*/
sinsize=sizeof(structsockaddrin);
newfd=accept(sockfd,(structsockaddr*)&their_addr,&sin_size))
]if(new_fd==-1)(
[perror("acceptn);
continue;
}
printff^Gotconnectionfrom%s\n",inet_ntoa(their_addr.sinaddr));
if(!fork()){/*子進(jìn)程*/
if(send(new_fd,nHello,world!'n",14,0)==-1)perror(nsendn);
close(newfd);
exit(0);
}
close(newfd);/*無(wú)法生成子進(jìn)程時(shí)有用*/
while(waitpid(-1,NULL,WNOHANG)>0);/*清除所有子進(jìn)程*/
TCP應(yīng)用舉例
Client部分
Client程序的作用
-程序初始化
■連接到某個(gè)Server上,建立socket連接
■與Server進(jìn)行通信和信息處理
■接收Server通過(guò)socket連接發(fā)送來(lái)的數(shù)據(jù),
進(jìn)行相應(yīng)處理
■通過(guò)socket連接向Server發(fā)送請(qǐng)求信息
■通信結(jié)束后中斷與Client的連接
一個(gè)簡(jiǎn)單的TCPClient
完整的Client程序示例
程序流程一
■取得socket描述符:
intsockfd;
sockfd=socket(AFJNET,SOCK_STREAM,
0);
程序流程二
?填寫(xiě)連接對(duì)方的地址信息的sockaddjin結(jié)構(gòu)
structhostent*he;
structsockaddrjntheir_addr;/*對(duì)方的地址
信息*/
he二gethostbyname("");
their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(4000);/*short,NBO
*/
their_addr.sin_addr="((structin_addr*)he-
>h_addr);
bzero(&(their_addr.sin_zero),8);/*其余部分設(shè)置成
0*/
程序流程三
■連接端口
connect(sockfd,(structsockaddr
*)&their_addr,sizeof(struct
sockaddr));
程序流程四
■讀寫(xiě)socket
程序流程五
■關(guān)閉socket
close(sockfd);
#include<stdio.h>
^include<stdlib.h>
^include<ermo.h>
^include<string.h>
Hnclude<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#definePORT3490/*Server的端口*/
#defineMAXDATASIZE100/*一次可以讀的最大字節(jié)數(shù)*/
intmain(intargc,char*argv[])
(
intsockfd,numbytes;
charbufIMAXDATASIZE];
structhostent*he;/*主機(jī)信息*/
structsockaddrintheiradd;/*對(duì)方地址信息*/
if(argc!=2){
fprintffstderr,"usage:clienthostname\nn);
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 自然主題探索課程設(shè)計(jì)
- 工程編制預(yù)算合同范例
- 房產(chǎn)贈(zèng)與合同范例6
- 供應(yīng)材料解除合同范例
- 公租房租賃合同租金退還流程3篇
- 博物館租賃協(xié)議模板文化展示3篇
- 農(nóng)作物種子買(mǎi)賣(mài)協(xié)議樣式3篇
- 地面施工合同中的工期延誤3篇
- 婚前房產(chǎn)協(xié)議書(shū)正規(guī)范本3篇
- 合同模板車位購(gòu)買(mǎi)合同3篇
- 全面設(shè)備保養(yǎng)TPM培訓(xùn)教材課件
- 二保焊作業(yè)指導(dǎo)書(shū)
- 垃圾焚燒發(fā)電廠項(xiàng)目給排水安裝工程專項(xiàng)方案
- DB64-T 1147-2022 寧夏工業(yè)單位產(chǎn)品能源消耗限額
- 授課比賽評(píng)分表
- XXXX供電項(xiàng)目可行性研究報(bào)告
- 抗菌藥物供應(yīng)目錄備案表
- TSG G0002-2010 鍋爐節(jié)能技術(shù)監(jiān)督管理規(guī)程
- cass實(shí)體名稱,圖層,實(shí)體代碼對(duì)照表
- 印刷工藝-ppt課件
- 員工訪談?dòng)涗洷硗暾麅?yōu)秀版
評(píng)論
0/150
提交評(píng)論