socket編程教學(xué)課件_第1頁(yè)
socket編程教學(xué)課件_第2頁(yè)
socket編程教學(xué)課件_第3頁(yè)
socket編程教學(xué)課件_第4頁(yè)
socket編程教學(xué)課件_第5頁(yè)
已閱讀5頁(yè),還剩48頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論