C++网络socket编程指南.ppt

上传人:牧羊曲112 文档编号:6154015 上传时间:2023-09-30 格式:PPT 页数:35 大小:231KB
返回 下载 相关 举报
C++网络socket编程指南.ppt_第1页
第1页 / 共35页
C++网络socket编程指南.ppt_第2页
第2页 / 共35页
C++网络socket编程指南.ppt_第3页
第3页 / 共35页
C++网络socket编程指南.ppt_第4页
第4页 / 共35页
C++网络socket编程指南.ppt_第5页
第5页 / 共35页
点击查看更多>>
资源描述

《C++网络socket编程指南.ppt》由会员分享,可在线阅读,更多相关《C++网络socket编程指南.ppt(35页珍藏版)》请在三一办公上搜索。

1、Socket,使用Win32 API,一個網路通訊程式,什麼是Socket,凡是網路兩端互相連線傳送資料時的溝通介面就是socket,是一個網路系統的通訊函式庫,在任何作業系統中可以通用主要的5大函式:socket()電話bind()線路(第幾分機?)listen()準備好接聽(啟用鈴聲)connect()撥電話出去accept()對方接聽,Socket函式,指定通訊協定,socket()函式,int SOCKET socket(int af,int type,int protocol);af:位址資料族系(family),用不同方式表示網路位址type:通訊方式Protocal:傳輸協定編號

2、回傳值:-1表示建立socket發生錯誤 若成功則回傳非負整數,稱為socket descriptor(socket描述子),選項設定,af:選擇AF_INET Internet address family對應的網路位址資料格式是unsigned long(無號長整數)type:SOCK_STREAM 虛擬路徑連接方式(TCP用)SOCK_DGRAM 資料包方傳遞式(UDP用)protocal:選擇IPPROTO_TCP(TCP通訊協定)或寫入0,交由系統設定,範例,SOCKET sock;/宣告sock=socket(/設定AF_INET,SOCK_STREAM,IPPROTO_TCP);

3、,Bind函式,指定本地端位置,Bind()函式,int bind(SOCKET s,const struct sockaddr*name,int namelen);s:指定好通訊協定的socket name:指定本地端位址,資料格式為sockaddrnamelen:name之資料長度(單位byte)回傳值:-1表錯誤,否則為0,Sockaddr_in 格式(IPv4用),struct sockaddr_in short sin_family;u_short sin_port;struct in_addr sin_addr;char sin_zero8;sin_family:位址資料族系,同樣

4、設定為AF_INETsin_port:主機開啟的通訊埠號 用htons()寫入sin_addr:主機IP位址 in_addr資料格式sin_zero8:目前沒用處,保留以後使用,in_addr格式,typedef struct in_addr union struct u_char s_b1,s_b2,s_b3,s_b4;S_un_b;struct u_short s_w1,s_w2;S_un_w;u_long S_addr;S_un;in_addr;使用了union的結構體,實際上的大小是一個32bit的長整數所以只要注意u_long S_addr這個變數 將IP對此變數寫入便可函式庫引入的

5、標頭檔應該會有定義#define s_addr S_un.s_addr此後只要對前一頁之變數sin_addr.s_addr存取便可寫入時使用inet_addr(“IP位址字串”)轉換成unsigned long,範例,SOCKET Sock;sockaddr_in saServer;Sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);/設定本機通訊用的位址saServer.sin_family=AF_INET;saServer.sin_port=htons(5150);/啟用5150 port=inet_addr(“140.115.65.30”);/設定本

6、機IP/呼叫Bind函式 bind(Sock,(SOCKADDR*),Listen函式 設定socket等待外部連線,listen()是使Socket進入等待連線狀態,等待客戶端(Client)連上線來,很顯然的呼叫此函式的主機,功能會是一台伺服器(Server)。如果有Client想要連過來,此時可以呼叫connect()來跟Server 連線。而Server接受後會建立新的socket和Client通訊,listen socket則繼續存在等待其他Client,直到關閉為止。,listen()函式,int listen(SOCKET s,int backlog);s:設定好bind(),並

7、且尚未連線的socketBacklog:等待Server接受連線前,同時最大連線數回傳值:-1表錯誤,否則為0,Accept函式 接受外部連線,Blocking Non-blocking,Accept()函式,SOCKET accept(SOCKET s,struct sockaddr*addr,int*addrlen);s:一個設定為listen狀態的socketsddr:Client端位址資訊,由函式自動產生填入addrlen:sddr長度,由函式自動產生回傳值:-1表示錯誤,否則傳回另一個包含Client端資訊的新socket descriptor,作為傳送資料用傳進accept()的l

8、isten socket本身並沒有辦法作資料的傳輸,所以必須透過accept()產生一個包含通訊協定、Server、Client資訊的新socket,利用他就可以進行資料的傳輸了,範例,ListenSocket 為一個bind()過且未連線的socket/設定socket為接聽外部連線用if(listen(ListenSocket,1)=SOCKET_ERROR)printf(Error listening on socket.n);/宣告一個用來和Client連線用的socket SOCKET AcceptSocket;/接受外部連線while(1)AcceptSocket=SOCKET_E

9、RROR;/尚未取得socket descriptor,等待外部連線進入時重設while(AcceptSocket=SOCKET_ERROR)AcceptSocket=accept(ListenSocket,NULL,NULL);printf(Client connected.n);break;,connect函式 與等待接聽的socket連線,Client端若要與Server溝通,必須透過connect建立連線,經過驗證確定連線成功後,才能進行資料傳輸。三向交握(three-way handshake)機制:1.Client向Server提出連線要求(connect()2.Server若接到

10、要求,則回應Clinet接到要求3.Client接到回應,向Server表示收到回覆至此才算連線建立完成,雙方可以開始交換資料若發生錯誤,則會由轉送中繼站回傳ICMP錯誤訊息connect函式讀到後,會回報錯誤給程式,connect()函式,int connect(SOCKET s,const struct sockaddr*name,int namelen);設定方式請參照bind()函式name內資料為回傳值:-1表錯誤,否則回傳0,recv(),send()函式 處理資料收送,從先前設定好Server與Client的通訊方式後,我們利用進行資料交換的函式recv(),send()來處理要

11、溝通的資料,其實資料溝通的函式有許多種類,read(),write(),readv(),writev(),recvmsg(),sendmsg()等等,我們介紹recv()和send()給大家入門,其他函式的使用可以查閱MSDN或 man 說明文件,recv()函式,int recv(SOCKET s,char*buf,int len,int flags);s:一個建立連線成功的socketbuf:呼叫recv,用來儲存收到資料的暫存器len:buf的長度(byte)flags:選擇工作模式,一般填入0回傳值:-1表錯誤,否則傳回接受到資料的長度(byte),send()函式,int send(

12、SOCKET s,const char*buf,int len,int flags);s:一個建立連線成功的socketbuf:用來儲存將送出資料的暫存器len:buf的長度(byte)flags:選擇工作模式,一般填入0回傳值:-1表錯誤,否則傳回送出資料的長度(byte),範例,/Server端int bytesSent;int bytesRecv=SOCKET_ERROR;char sendbuf32=Server:Sending Data.;char recvbuf32=;bytesRecv=recv(m_socket,recvbuf,32,0);printf(Bytes Recv:%

13、ldn,bytesRecv);bytesSent=send(m_socket,sendbuf,strlen(sendbuf),0);printf(Bytes Sent:%ldn,bytesSent);/Client端int bytesSent;int bytesRecv=SOCKET_ERROR;char sendbuf32=Client:Sending data.;char recvbuf32=;bytesSent=send(m_socket,sendbuf,strlen(sendbuf),0);printf(Bytes Sent:%ldn,bytesSent);while(bytesRec

14、v=SOCKET_ERROR)bytesRecv=recv(m_socket,recvbuf,32,0);if(bytesRecv=0|bytesRecv=WSAECONNRESET)printf(Connection Closed.n);break;if(bytesRecv 0)return;printf(Bytes Recv:%ldn,bytesRecv);,closesocket(),shutdown()函式 中斷連線,在accept()或connect()成功後建立的通訊用socket,必須由Client或Server下達closesocket()或shutdown()來結束連線。cl

15、osesocket()可以用來終止TCP連線,但不會馬上關閉,必須等到該socket不在動作後才切斷連線,這和TCP協定中使用到的sliding window有關,這是用完再關的函式,而shutdown()是有強制性質的中斷連線函式,用來控制socket的IO。一個好的中斷連線作法應有四步:1.結束傳送資料2.使用shutdown(),設定為禁止送出資料3.呼叫recv(),確定收到的資料長度為0,避免遺漏資訊4.closesocket()來關閉socket註:在Winsock中使用的closesocket()和BSD socket中的close()是相同的,closesocket()與 sh

16、utdown()函式,int closesocket(SOCKET s);int shutdown(SOCKET s,int how);s:使用中的socket how:控制socket工作的方式SD_RECEIVE 禁止輸入(disable recv()函式)SD_SEND 禁止輸出(disable send()函式)SD_BOTH 雙向禁止回傳值:-1表錯誤,否則傳回0,Server-Client Model,recv()send(),WINSOCKETS,#include,WINSOCKETS,WSADATA wsadata;if(WSAStartup(0 x101,(LPWSADATA

17、),WINSOCKETS,WSACleanup();,Server端用到的元件,ListBox 顯示項目清單可以利用 ListBox1-Items-Add()新增資料或是ListBox1-Items-Insert()插入資料Add(字串),Insert(位置,字串)由於本次Server端只用到這一個元件,直接拉到滿版,Server端用到的元件,Timer 計時器等待,定時輪詢,Server端用到的語法,#define A B 定義A為B,如利用#define Add(Text)ListBox1-Items-Insert(0,Text)這樣就可以用簡短的Add(“文字”)指令取代一長串的Insert指令註:#define只會增加編譯時間(要轉換),對於程式的實際效能毫無影響,Server端的工作流程,程式啟動直接開始監聽工作WSAStartupsocketbindlisten程式結束時關閉連線shutdownclosesocket,Server端的工作流程,用Timer做定時監測若已經連線 recv接收資料 否則 accept 接受連線!accept&recv 在沒有資料進入(沒人連線或沒有資料)時會阻塞住導致程式停止回應,Server停止回應的處理方法,1.用非阻塞式函數WSAAcceptExWSARecvWaitForSingleObject2.多執行緒3.中斷法,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号