久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Socket網(wǎng)絡(luò)編程指導(dǎo)

 千杯不醉004 2011-03-19

Socket網(wǎng)絡(luò)編程指導(dǎo)

2011-3-19

1/37

[email protected]

什么是Socket

2011-3-19

2/37

BSD Socket(伯克立套接字)是通過(guò)標(biāo)準(zhǔn)的UNIX文件描述符和其它程序通訊的一個(gè)方法,,目前已經(jīng)被廣泛移植到各個(gè)平臺(tái)。

 

Socket是獨(dú)立于具體協(xié)議的網(wǎng)絡(luò)編程接口。在ISO模型中,,主要位于會(huì)話層和傳輸層。

Socket的類(lèi)型

2011-3-19

3/37

流式套接字(SOCK_STREAM)
    
提供了一個(gè)面向連接,,可靠的數(shù)據(jù)傳輸服務(wù),,數(shù)據(jù)無(wú)差錯(cuò),,無(wú)重復(fù)的發(fā)送且按發(fā)送順序接收。內(nèi)設(shè)流量控制,,避免數(shù)據(jù)流超限,;數(shù)據(jù)被看作是字節(jié)流,無(wú)長(zhǎng)度限制,。

 

數(shù)據(jù)報(bào)式套接字(SOCK_DGRAM)
    
提供了一個(gè)無(wú)連接服務(wù),。數(shù)據(jù)包以獨(dú)立包形式被發(fā)送,不提供無(wú)差錯(cuò)保證,數(shù)據(jù)可能丟失或重復(fù),,并且接收順序無(wú)序,。

 

原始式套接字(SOCK_RAW)
    
該接口允許對(duì)較低層次協(xié)議,如IP,、ICMP直接訪問(wèn),。

2011-3-19

4/37

Socket所在層次示意圖

Application program

Stream

Socket

Interface

TCP

UDP

Datagram

Socket

Interface

Raw

Socket

Interface

IP

Physical and data link layers

基本套接字調(diào)用

2011-3-19

5/37

創(chuàng)建套接字    socket();
綁定本機(jī)端口       bind();
建立連接              connect();

       接受連接              accept();
監(jiān)聽(tīng)端口              listen();
數(shù)據(jù)傳輸              send(), recv() ;
關(guān)閉套接字    close();

Socket相關(guān)的數(shù)據(jù)結(jié)構(gòu)

2011-3-19

6/37

struct sockaddr_in

   {
   short int   sin_family;      /* 通信類(lèi)型 */
   unsigned short int   sin_port;  /* 端口號(hào),網(wǎng)絡(luò)字節(jié)順序*/
   struct in_addr  sin_addr;  /* Internet 地址,網(wǎng)絡(luò)字節(jié)順序*/
   unsigned char sin_zero[8];   /*沒(méi)用*/

    };

 

struct in_addr

    {

             in_addr_t    s_addr;  /* 存儲(chǔ)32bit IP地址*/

    }

網(wǎng)絡(luò)字節(jié)順序和主機(jī)字節(jié)順序

2011-3-19

7/37

Big-Endian Byte Order:字節(jié)的高位在內(nèi)存中放在存儲(chǔ)單元的起始位置

00001010

00010111

00001110

00000110

00001010

00010111

00001110

00000110

Memory

Little-Endian Byte Order : Big-Endian相反

A

A+1

A+2

A+3

2011-3-19

8/40

Host byte order Little-Endian

16-bit

32-bit

Network byte orderBig-Endian

16-bit

32-bit

htons()

ntohs()

htonl()

ntohl()

網(wǎng)絡(luò)字節(jié)順序和主機(jī)字節(jié)順序的轉(zhuǎn)換

IP地址的轉(zhuǎn)換

2011-3-19

9/37

int inet_aton(const char* strptr, struct in_addr                       *addrptr);

   從點(diǎn)狀十進(jìn)制到322進(jìn)制的轉(zhuǎn)換,如“202.38.64.185

   11001010,,00100110,,0100000010111001

char  *inet_ntoa(struct in_addr inadd);

   inet_aton()的功能相反

相關(guān)的內(nèi)存操作函數(shù)

2011-3-19

10/37

void *memset(void *buffer, int c, int count);

    buffer所指內(nèi)存區(qū)域的前count個(gè)字節(jié)設(shè)置成字符c,。

void *memcpy(void *dest, void *src, unsigned int                                    count);

   src所指內(nèi)存區(qū)域復(fù)制count個(gè)字節(jié)到dest所指內(nèi)存區(qū)域,。

Void bzero(void *s, int n );

    置字節(jié)字符串s的前n個(gè)字節(jié)為零。

域名和IP地址的轉(zhuǎn)換

2011-3-19

11/37

struct hostent *gethostbyname(const char *name);

struct hostent

{
 char    *h_name; /* 主機(jī)的官方域名 */
 char  **h_aliases; /* 一個(gè)以NULL結(jié)尾的主機(jī)別名數(shù)組 */
 int  h_addrtype; /* 返回的地址類(lèi)型,,在Internet環(huán)境下為AF-                                 INET */
 int  h_length; /* 地址的字節(jié)長(zhǎng)度 */
 char  **h_addr_list; /* 一個(gè)以0結(jié)尾的數(shù)組,,包含該主機(jī)的所有地                     */
};
#define h_addr h_addr_list[0]  /*
h-addr-list中的第一個(gè)地址*/

建立Socket

2011-3-19

12/37

int socket(int domain, int type, int protocol);

參數(shù)說(shuō)明:

       domain:通信使用的協(xié)議族,即網(wǎng)絡(luò)的類(lèi)型,,對(duì)于             TCP/IP來(lái)說(shuō),,是AF_INET

    type: SOCK_STREAM / SOCK_DGRAM

    protocol: 通常為0

 

 返回整形的socket描述符,如果出錯(cuò),,返回-1

Socket的配置

2011-3-19

13/37

Socket描述符是一個(gè)指向內(nèi)部數(shù)據(jù)結(jié)構(gòu)的指針,,它指向描述符表入口。調(diào)用Socket()函數(shù)時(shí),,將建立一個(gè)Socket,,為一個(gè)Socket數(shù)據(jù)結(jié)構(gòu)分配存儲(chǔ)空間。

兩個(gè)網(wǎng)絡(luò)程序之間的一個(gè)網(wǎng)絡(luò)連接包括五種信息:通信協(xié)議,、本地主機(jī)地址和端口,、遠(yuǎn)端主機(jī)地址和端口。

在使用socket進(jìn)行網(wǎng)絡(luò)傳輸以前,,必須配置該socket,。       面向連接的socket客戶端調(diào)用connect()函數(shù)在socket數(shù)據(jù)結(jié)構(gòu)中保存本地和遠(yuǎn)端信息,。

              無(wú)連接socket的客戶端和服務(wù)端以及面向連接socket的服務(wù)端通過(guò)調(diào)用bind()函數(shù)來(lái)配置本地信息,。

綁定Socket

2011-3-19

14/37

int bind(int sockfd,,struct sockaddr_in *my_addr, int                   addrlen);

    sockfdsocket()返回的socket描述符;

    my_addr是指向包含本機(jī)IP地址及端口號(hào)等信息的                      sockaddr類(lèi)型的指針,;                                          addrlen一般被設(shè)置為sizeof(struct sockaddr_in)


成功被調(diào)用時(shí)返回0,;出現(xiàn)錯(cuò)誤時(shí)返回"-1" 

綁定前sockaddr_in的初始化

2011-3-19

15/37

my_addr.sin_family = AF_INET;     //選擇網(wǎng)絡(luò)類(lèi)型為TCP/IP

my_addr.sin_addr.s_addr = inet_addr(“210.45.64.222");

my_addr.sin_port = htons( 8888 );  //選擇端口8888

addr_len = sizeof(struct sockaddr_in);               

memset(&my_addr.sin_zero, ‘\0’, sizeof(my_addr.sin_zero));  

建立連接(客戶端)

2011-3-19

16/37

面向連接的客戶程序使用connect函數(shù)來(lái)配置socket并與遠(yuǎn)端服務(wù)器建立一個(gè)TCP連接,其函數(shù)原型為:
int connect( int sockfd, struct sockaddr_in                                 *serv_addr
,,int addrlen);

serv_addr是包含遠(yuǎn)端主機(jī)IP地址和端口號(hào)的指針,;addrlen是遠(yuǎn)端地址結(jié)構(gòu)的長(zhǎng)度

成功則返回0,出現(xiàn)錯(cuò)誤時(shí)返回-1

建立連接(服務(wù)器端)

2011-3-19

17/37

服務(wù)器監(jiān)聽(tīng)端口:listen函數(shù)使socket處于被動(dòng)的監(jiān)聽(tīng)模式,,并為該socket建立一個(gè)輸入數(shù)據(jù)隊(duì)列,,將到達(dá)的服務(wù)請(qǐng)求保存在此隊(duì)列中,直到程序處理它們,。
int listen(int sockfd
,, int backlog);

backlog:請(qǐng)求連接隊(duì)列的最大長(zhǎng)度

成功返回0,出錯(cuò)返回-1

建立連接(服務(wù)器端)

2011-3-19

18/37

accept()函數(shù)讓服務(wù)器接收客戶的連接請(qǐng)求,。在建立好輸入隊(duì)列后,,服務(wù)器就調(diào)用accept函數(shù),然后睡眠并等待客戶的連接請(qǐng)求,。
int accept(int sockfd, sockaddr_in *addr, int                   *addrlen);

addr是指向sockaddr_in變量的指針,,該變量存放提出連接請(qǐng)求服務(wù)的主機(jī)的信息

返回新的socket描述符,和請(qǐng)求連接進(jìn)程的地址聯(lián)系起來(lái)在新的socket描述符上進(jìn)行數(shù)據(jù)傳輸操作,。原來(lái)的socket繼續(xù)listen

數(shù)據(jù)傳輸(1)

2011-3-19

19/37

send()recv()這兩個(gè)函數(shù)用于面向連接的socket上進(jìn)行數(shù)據(jù)傳輸,。
send()
函數(shù)原型為:
int send(int sockfd, const void *msg, int len, int                      flags);     
    sockfd
是用來(lái)傳輸數(shù)據(jù)的socket描述符;msg是指向要發(fā)送數(shù)據(jù)的指針,;len是以字節(jié)為單位的數(shù)據(jù)長(zhǎng)度,;flags一般置為0

send() 返回實(shí)際發(fā)送的字節(jié)數(shù),可能會(huì)少于希望發(fā)送的數(shù)據(jù),。在程序中應(yīng)該將send()的返回值與欲發(fā)送的字節(jié)數(shù)進(jìn)行比較,。當(dāng)返回值與len不匹配時(shí),應(yīng)該進(jìn)行處理,。

數(shù)據(jù)傳輸(2)

2011-3-19

20/37

recv()函數(shù)原型為:
int recv(int sockfd, void *buf, int len, unsigned int            flags);

buf 是存放接收數(shù)據(jù)的緩沖區(qū),;len是緩沖區(qū)的長(zhǎng)度。flags也被置為0,。

recv()返回實(shí)際接收的字節(jié)數(shù),,當(dāng)出現(xiàn)錯(cuò)誤時(shí),返回-1

數(shù)據(jù)傳輸(3)

2011-3-19

21/37

sendto()recvfrom()用于在無(wú)連接的數(shù)據(jù)報(bào)socket

    式下進(jìn)行數(shù)據(jù)傳輸,。由于本地socket沒(méi)有與遠(yuǎn)端機(jī)器建立連接,,所以在發(fā)送數(shù)據(jù)時(shí)要指明目的地址。
     

sendto()函數(shù)原型為:

    int sendto(int sockfd, const void *bufint buflen,,                 unsigned  int flags, const struct                             sockaddr_in *to,  int tolen); 

數(shù)據(jù)傳輸(4)

2011-3-19

22/37

recvfrom()函數(shù)原型為:
int recvfrom(int sockfd
,,void *bufint buflen,,                          unsigned int flags,,struct sockaddr_in                        *fromint  *fromlen);

 

recvfrom()函數(shù)返回接收到的字節(jié)數(shù),,當(dāng)出錯(cuò)時(shí)返回-1

結(jié)束傳輸

2011-3-19

23/37

close()函數(shù)用于釋放socket,,停止在該socket上的任何數(shù)據(jù)操作:     close(sockfd);
    

也可以調(diào)用shutdown() 來(lái)關(guān)閉該socket

       該函數(shù)允許只停止某個(gè)方向上的數(shù)據(jù)傳輸,而一個(gè)方向上的數(shù)據(jù)傳輸繼續(xù)進(jìn)行,。
    int shutdown(int sockfd
,,int how);
   
參數(shù) how允許為shutdown操作選擇以下幾種方式:
    0-------
不允許繼續(xù)接收數(shù)據(jù)
    1-------
不允許繼續(xù)發(fā)送數(shù)據(jù)
    2-------
不允許繼續(xù)發(fā)送和接收數(shù)據(jù),
    shutdown
在操作成功時(shí)返回0,,出錯(cuò)時(shí)返回-1,。

C/S結(jié)構(gòu)

2011-3-19

24/37

服務(wù)器端要先啟動(dòng),提供相應(yīng)服務(wù):

  1:打開(kāi)一通信通道并告知本地主機(jī),,它愿意在某一個(gè)公認(rèn)地址上接收客戶請(qǐng)求,。

  2:等待客戶請(qǐng)求到達(dá)該端口。

  3:接收到服務(wù)請(qǐng)求,,處理該請(qǐng)求并發(fā)送應(yīng)答信號(hào),。

  4:返回第二步,等待另一客戶請(qǐng)求

  5:關(guān)閉服務(wù)器,。

客戶端:

  1,、打開(kāi)一通信通道,并連接到服務(wù)器所在主機(jī)的特定端口,。

  2,、向服務(wù)器發(fā)送服務(wù)請(qǐng)求報(bào)文,等待并接收應(yīng)答,;繼續(xù)提出請(qǐng)求……

  3,、請(qǐng)求結(jié)束后關(guān)閉通信通道并終止。

流程圖

2011-3-19

25/37

TCP服務(wù)器端

(循環(huán)服務(wù)器)

TCP客戶端

socket( )

bind( )

listen( )

accept( )

socket( )

send( )

connect( )

recv( )

recv( )

send( )

close( )

close( )

UDP服務(wù)器端

UDP客戶端

socket( )

bind( )

listen( )

recvfrom( )

sendto( )

socket( )

bind( )

close( )

close( )

簡(jiǎn)單的例子

2011-3-19

26/37

int sockfd, newsockfd,addr_len, sendnum;

struct sockaddr_in my_addr, their_addr;

char * msg = “welcome”;

sockfd = socket( AF_INET, SOCK_STREAM, 0 );  //建立socket

 

my_addr.sin_family = AF_INET;                           //選擇網(wǎng)絡(luò)類(lèi)型為TCP/IP

my_addr.sin_addr.s_addr = inet_addr(“210.45.64.222");

my_addr.sin_port = htons( 8888 );                        //選擇端口8888

addr_len = sizeof( struct sockaddr_in);               

memset(&my_addr.sin_zero, ‘\0’, sizeof(my_addr.sin_zero));  

 

bind(sockfd, (struct sockaddr *)&my_addr, addr_len);   //綁定socket

 

listen(sockfd,10);         //監(jiān)聽(tīng),等待連接,等待連接隊(duì)列最大長(zhǎng)度為10

簡(jiǎn)單的例子(續(xù))

2011-3-19

27/37

While( 1 )

{

       newsockfd = accept( sockfd, (struct sockaddr *)&my_addr, addr_len);

      sendnum = send(newsockfd, msg, strlen(msg)+1, 0);

      ……

      close(newsockfd);

 }

 

 close(sockfd);

阻塞與非阻塞(1)

2011-3-19

28/37

阻塞函數(shù):指其完成指定的任務(wù)之前不允許程序調(diào)用另一個(gè)函數(shù),,在Windows下還會(huì)阻塞本線程消息的發(fā)送。

    eg: recv( ) ,當(dāng)socket工作在阻塞模式的時(shí)候,,如果沒(méi)有數(shù)據(jù)的情況下調(diào)用該函數(shù),則當(dāng)前線程會(huì)被掛起,,直到有數(shù)據(jù)為止,。

 

非阻塞函數(shù):指操作啟動(dòng)之后,,如果可以立即得到結(jié)果就返回結(jié)果,否則返回表示結(jié)果需要等待的錯(cuò)誤信息,,不等待任務(wù)完成函數(shù)就返回,。

使用非阻塞I/O的方式:select()

例子:

while(1){//執(zhí)行循環(huán) 一邊輸出一邊也不要忘了輸入

              FD_ZERO(&wt_set); FD_ZERO(&rd_set);

              FD_CLR(s,&wt_set); FD_CLR(s,&rd_set);

              FD_SET(s,&wt_set); FD_SET(s,&rd_set);

          timeout.tv_sec = 0;

              timeout.tv_usec =500000;

                 z=select(s+1,&rd_set,&wt_set,NULL,&timeout);

            if(FD_ISSET(s,&rd_set)){//有數(shù)據(jù)可讀

                          z=recv(s,&recvBuff,sizeof recvBuff-1,0);

2011-3-19

29/37

阻塞與非阻塞(2)

2011-3-19

30/37

Berkeley socket函數(shù)部分中,不涉及網(wǎng)絡(luò)I/O,、本地端工作的函數(shù)是非阻塞函數(shù)

Berkeley socket函數(shù)部分中,,網(wǎng)絡(luò)I/O的函數(shù)是可阻塞函數(shù),,也就是它們可以阻塞執(zhí)行,,也可以不阻塞執(zhí)行。這些函數(shù)都使用了一個(gè)socket,,如果它們使用的socket是阻塞的,,則這些函數(shù)是阻塞函數(shù);如果它們使用的socket是非阻塞的,,則這些函數(shù)是非阻塞函數(shù),。

并發(fā)服務(wù)器

2011-3-19

31/37

TCP服務(wù)器端(并發(fā)服務(wù)器)

socket( )

bind( )

listen( )

accept( )

send( )

recv( )

close( )

fork( ) //派生新進(jìn)程

close( )

主進(jìn)程在accept之后派生新進(jìn)程,然后主進(jìn)程繼續(xù)listen,處理新的連接請(qǐng)求

     新進(jìn)程自行和客戶端通信,,新進(jìn)程和主進(jìn)程搶占CPU

WinSock API

2011-3-19

32/37

WinSock是一個(gè)基于Socket模型的API,,在Microsoft Windows操作系統(tǒng)類(lèi)中使用。

它在Berkeley接口函數(shù)的基礎(chǔ)之上,,還增加了基于消息驅(qū)動(dòng)機(jī)制的Windows擴(kuò)展函數(shù),。

Winscok1.1只支持TCP/IP網(wǎng)絡(luò),WinSock2.0增加了對(duì)更多協(xié)議的支持。

Windows下的Socket編程(1)

2011-3-19

33/37

linux下基本相同,,需要包含winsock2.h

需要使用Ws_32.lib,,可以用以下語(yǔ)句通告程序編譯時(shí)調(diào)用該庫(kù):

    #pragma comment(lib,"Ws2_32.lib") ;

WinSockDLL的形式提供,在調(diào)用任何WinSock API之前,,必須調(diào)用函數(shù)WSAStartup()進(jìn)行初始化,,最后,調(diào)用函數(shù)WSACleanUp()作清理工作,。

Windows下的Socket編程(2)

2011-3-19

34/37

WSADATA wsd;

//設(shè)置WINSOCK的版本

WORD wVersionRequested=MAKEWORD(2,2);

WSAStartup(wVersionRequested,&wsd) ; //初始化

 ,。。,。,。。,。,。。,。    

 WSACleanUp();

Windows下的Socket編程(3)

2011-3-19

35/37

MFC提供了兩個(gè)類(lèi)CAsyncSocketCSocket來(lái)封裝WinSock API,,提供了更簡(jiǎn)單的網(wǎng)絡(luò)編程接口,。

CAsyncSocket在較低層次上封裝了WinSock API,缺省情況下,,使用該類(lèi)創(chuàng)建的socket是非阻塞的socket,,所有操作都會(huì)立即返回,如果沒(méi)有得到結(jié)果,,返回WSAEWOULDBLOCK,,表示是一個(gè)阻塞操作。

Windows下的Socket編程(4)

2011-3-19

36/37

CSocketCAsyncSocket的派生類(lèi),,缺省情況下使用該類(lèi)創(chuàng)建的socket是非阻塞的socket,,但是CSocket的網(wǎng)絡(luò)I/O是阻塞的,它在完成任務(wù)之后才返回,。

CSocket的阻塞不是建立在“阻塞”socket的基礎(chǔ)上,,而是在“非阻塞”socket上實(shí)現(xiàn)的阻塞操作

網(wǎng)絡(luò)編程作業(yè)要求

2011-3-19

37/37

 

不分組,每人獨(dú)立完成,。

基于C/SP2P結(jié)構(gòu),,使用UDPTCP協(xié)議皆可。

最好使用基本SOCKET API,不反對(duì)使用CAsyncSocket

   CSocket類(lèi),,但不準(zhǔn)使用和傳輸相關(guān)的控件,。

期末提交設(shè)計(jì)文檔,源碼,,及可執(zhí)行文件,。

提交時(shí)間為12月份,具體提交日期及提交方式待定,。

可選題目I

BBS發(fā)帖程序

通過(guò)term方式(202.38.64.3:23)或者通過(guò)web方式

完成在test版發(fā)一貼的功能(多發(fā)會(huì)被永久封賬號(hào))

Bbs賬號(hào)和密碼使用命令行參數(shù)或其他方式設(shè)置,,不要直接寫(xiě)在程序里

對(duì)于term方式下的程序,要求能監(jiān)視程序運(yùn)行過(guò)程(也就是說(shuō)在程序運(yùn)行的時(shí)候要把服務(wù)器的輸出打印到屏幕)

Referrence:

http協(xié)議:http://en./wiki/HTTP

2011-3-19

38/37

可選題目II

完成一個(gè)HTTP服務(wù)器

使用HTTP 1.1協(xié)議

支持最大至少10個(gè)并發(fā)連接(fork創(chuàng)建子進(jìn)程)

要求服務(wù)器程序運(yùn)行以后,,能在瀏覽器中訪問(wèn)文件,,正常顯示

Web server的根目錄使用命令行參數(shù)或者其他方式制定,不要寫(xiě)在程序代碼里

文件不存在時(shí)返回瀏覽器404錯(cuò)誤

2011-3-19

39/37

2011-3-19

40/37

謝謝

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多