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

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Socket編程

培訓思路:

■Socket是什么玩意

■咋使用和設(shè)計Socket進行通信

socket概述

linux中的網(wǎng)絡(luò)編程通過socket接口實現(xiàn)。Socket

既是一種特殊的10,它也是一種文件描述符。

一個完整的Socket都有一個相關(guān)描述{協(xié)議,

本地地址,本地端口,遠程地址,遠程端口};

每一個Socket有一個本地的唯一Socket號,

由操作系統(tǒng)分配。

文件描述符

■內(nèi)核(kernel)利用文件描述符(file

descriptor)來訪問文件。文件描述符是

非負整數(shù)。打開現(xiàn)存文件或新建文件時,

內(nèi)核會返回一個文件描述符。讀寫文件

也需要使用文件描述符來指定待讀寫的

文件

常見套接字有二種類型:

流式套接字(SOCK_STREAM)

■流式的套接字可口提供可靠的、面向連接的

通訊流。它使用了TCP協(xié)議。TCP保證了數(shù)據(jù)

傳輸?shù)恼_性和順序性。

■數(shù)據(jù)報套接字(SOCK_DGRAM)

■數(shù)據(jù)報套接字定義?一種無連接的服務(wù),數(shù)

據(jù)通過相互獨立的報文進行傳輸,是無序的,

并且不保證可靠,無差錯。使用數(shù)據(jù)報協(xié)議

UDP協(xié)議。

如何使用和設(shè)計Socket進行通信

■Socket的建立、配置、連接、數(shù)據(jù)傳輸、

結(jié)束

■以上的主要步驟由socket函數(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;

這個數(shù)據(jù)結(jié)構(gòu)是由于歷史原因保留下來的,主

要用作與以前的格式兼容。

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填本機IP,如果此項填

INADDR_ANY時,表示自動取本機IP填入該項(僅

用于Server)

函數(shù)簡介:socket

■Socket描述符與Linux中的文件描述符類似,也

是一個int型的變量

-函數(shù)調(diào)用:

■intsocket(intdomain,inttype,intprotocol);

-函數(shù)返回Socket描述符,返回-1表示出錯

■domain參數(shù)只能取AF」NET,protocol參數(shù)一般取0

■應用示例:

-TCP:sockfd=socket(AF_INETzSOCK_STREAMzO);

-UDP:sockfd=socket(AF_INET,SOCK_DGRAMzO);

函數(shù)簡介:bind

■作為Server程序,需要與一個端口綁定

intbind(intsockfd,structsockaddr*my_addr,

intaddrlen);

bind函數(shù)返回-1表示出錯,最常見的錯誤是該

端口已經(jīng)被其他程序綁定。

需要注意的一點:在Linux系統(tǒng)中,1024以下的

端口只有擁有root權(quán)限的程序才能綁定

函數(shù)簡介:listen

■開始監(jiān)聽已經(jīng)綁定的端口

-需要在此前調(diào)用bind。函數(shù),否則由系統(tǒng)指定一個

隨機的端口

■intlisten(intsockfd,intqueuejength);

■接收隊列

-一個新的Client的連接請求先被放在接收隊列中,

等待Server程序調(diào)用accept函數(shù)接受連接請求

■queue_length指的就是接收隊列的長度

也就是在Server程序調(diào)用accept函數(shù)之前最大允許的連接請

求數(shù),多余的連接請求將被拒絕

函數(shù)簡介:accept

■accept。函數(shù)將響應連接請求,建立連接

■產(chǎn)生一個新的socket描述符來描述該連接

■這個連接用來與特定的Client交換信息

■intaccept(intsockfd,structsockaddr*addr,int

*addrlen);

■addr將在函數(shù)調(diào)用后被填入連接對方的地址

信息,如對方的IP、端口等。

■accept缺省是阻塞函數(shù),阻塞直到有連接請求

函數(shù)簡介:connect

連接某個Server

intconnect(intsockfd,structsockaddr*servaddr,

intaddrlen);

■servaddr是事先填寫好的結(jié)構(gòu),Server的IP和端口都

在該數(shù)據(jù)結(jié)構(gòu)中指定。

函數(shù)簡介:recv

用于TCP協(xié)議中接收信息

intrecv(intsockfd,void*buf,intlen,intflags);

-buf,對向容納接收信息的緩沖區(qū)的指針

■len,緩沖區(qū)的大小

■flags,接收標志

■函數(shù)返回實際接收的字節(jié)數(shù),返回-1表示出錯

■recv缺省是阻塞函數(shù),直到接收到信息或出錯

函數(shù)簡介:send

用于TCP協(xié)議中發(fā)送信息

intsend(intsockfd,constvoid*msg,intlen,int

flags);

-msg,指向待發(fā)送信息的指針

-len,待發(fā)送的字節(jié)數(shù)

-flags,發(fā)送標志

■函數(shù)返回已發(fā)送的字節(jié)數(shù),返回-1表示出錯

■send缺省是阻塞函數(shù),直到發(fā)送完畢或出錯

-注意:如果函數(shù)返回值與參數(shù)len不相等,則剩

余的未發(fā)送信息需要再次發(fā)送

函數(shù)簡介:close

■關(guān)閉特定的socket連接

■調(diào)用函數(shù):intclose(intsockfd);

-關(guān)閉連接將中斷對該socket的讀寫操作。

■關(guān)閉用于listen。函數(shù)的socket將禁止其

他Client的連接請求

函數(shù)簡介:shutdown

■Shutdown。函數(shù)可以單方面的中斷連接,

即禁止某個方向的信息傳遞。

-函數(shù)調(diào)用

■intshutdown(intsockfd,inthow);

■參數(shù)how:

0-禁止接收信息

]-禁止發(fā)送信息

2-晶收和發(fā)il嬴被禁止,與dose()函數(shù)效果相同

■返回。表示調(diào)用成功,返回-1表示出錯

函數(shù)簡介:inetaddr,inet_ntoa

unsignedlonginet_addr(constchar*cp);

■inet_addr將一個點分十進制IP地址字符串轉(zhuǎn)換

成3萬位數(shù)字表示的IP地址

char*inet_ntoa(structin_addrin);

■inejntoa將一個32位數(shù)字表示的IP地址轉(zhuǎn)換

成點分十進制IP地址字符串

這兩個函數(shù)互為反函數(shù)

TCP:基于連接流的網(wǎng)絡(luò)協(xié)議

■TCP相關(guān)的函數(shù)

■Server的例子

■Client的例子

■Server-Client結(jié)構(gòu)圖

TCP應用舉例

Server部分

Server程序的作用

■程序初始化

■持續(xù)監(jiān)聽一個固定的端口

■收到Client的連接后建立一個socket連接

■與Client進行通信和信息處理

-接收Client通過socket連接發(fā)送來的數(shù)據(jù),

進行相應處理并返回處理結(jié)果,如BBS

Server

■通過socket連接向Client發(fā)送信息,

如TimeServer

■通信結(jié)束后中斷與Client的連接

一個簡單的TCPServer

完整的Server程序不例

程序流程一

■取得socket描述符:

intsockfd;

sockfd=socket(AFJNET,SOCK_STREAM,

0);

程序流程二

■填寫自身地址信息的sockaddr_in結(jié)構(gòu)

structsockaddrjnmy_addr;/*自身的地

址信息*/

my_addr.sin_family=AF_INET;

/*網(wǎng)絡(luò)字節(jié)順序*/

my_addr,sin_port=htons(MYPORT);

/*百動填本機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)聽端口

#defineBACKLOG10

listen(sockfd,BACKLOG);

程序流程五

-接受連接請求

intnew_fd;/*數(shù)據(jù)端口*/

structsockaddrjntheir_addr;/*連接對方的

地址信息*/

intsinsize;

sin_size=sizeof(structsockaddrjn);

new_fd=accept(sockfd,(structsockaddr

*)&their_addr,&sin_size))

程序流程六

■產(chǎn)生新進程(線程)處理讀寫socket

if(!fork()){/*子進程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)聽端口*/

#defineBACKLOG10/*listen的請求接收隊列長度*/

voidmain()

(

intsockfd,newfd;/*監(jiān)聽端口,數(shù)據(jù)端口*/

structsockaddrinmy_addr;/*自身的地址信息*/

structsockaddrintheiraddr;/*連接對方的地址信息*/

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;/*自動填本機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()){/*子進程*/

if(send(new_fd,nHello,world!'n",14,0)==-1)perror(nsendn);

close(newfd);

exit(0);

}

close(newfd);/*無法生成子進程時有用*/

while(waitpid(-1,NULL,WNOHANG)>0);/*清除所有子進程*/

TCP應用舉例

Client部分

Client程序的作用

-程序初始化

■連接到某個Server上,建立socket連接

■與Server進行通信和信息處理

■接收Server通過socket連接發(fā)送來的數(shù)據(jù),

進行相應處理

■通過socket連接向Server發(fā)送請求信息

■通信結(jié)束后中斷與Client的連接

一個簡單的TCPClient

完整的Client程序示例

程序流程一

■取得socket描述符:

intsockfd;

sockfd=socket(AFJNET,SOCK_STREAM,

0);

程序流程二

?填寫連接對方的地址信息的sockaddjin結(jié)構(gòu)

structhostent*he;

structsockaddrjntheir_addr;/*對方的地址

信息*/

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));

程序流程四

■讀寫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;/*主機信息*/

structsockaddrintheiradd;/*對方地址信息*/

if(argc!=2){

fprintffstderr,"usage:clienthostname\nn);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論