好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

C网络socket编程指南.ppt

36页
  • 卖家[上传人]:壹****1
  • 文档编号:591500229
  • 上传时间:2024-09-18
  • 文档格式:PPT
  • 文档大小:303.50KB
  • / 36 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • Socket使用Win32 API2021/3/111 一個網路通訊程式2021/3/112 什麼是Socket凡是網路兩端互相連線傳送資料時的溝通介面就是socket,是一個網路系統的通訊函式庫,在任何作業系統中可以通用主要的5大函式:socket()  電話bind()  線路(第幾分機?)listen()  準備好接聽(啟用鈴聲)connect()  撥電話出去accept()  對方接聽2021/3/113 Socket函式,指定通訊協定2021/3/114 socket ( )函式int SOCKETint SOCKET socket(socket( intint af, ,intint type, , intint protocol );); af :位址資料族系(family),用不同方式表示網路位址type:通訊方式Protocal:傳輸協定編號回傳值:-1表示建立socket發生錯誤 若成功則回傳非負整數,稱為socket descriptor (socket描述子)2021/3/115 選項設定af: 選擇AF_INET  Internet address family對應的網路位址資料格式是unsigned long(無號長整數)type:SOCK_STREAM 虛擬路徑連接方式(TCP用) SOCK_DGRAM 資料包方傳遞式(UDP用)protocal:選擇IPPROTO_TCP (TCP通訊協定) 或寫入0,交由系統設定2021/3/116 範例SOCKET sock;//宣告sock = socket(//設定AF_INET, SOCK_STREAM, IPPROTO_TCP); 2021/3/117 Bind函式,指定本地端位置2021/3/118 Bind()Bind()函式函式intint bind(bind(SOCKETSOCKET s, , const struct sockaddr*const struct sockaddr* name, , intint namelen ););s : : 指定好通訊協定的socket name : 指定本地端位址,資料格式為sockaddrsockaddrnamelen : : name之資料長度(單位byte)回傳值:-1表錯誤,否則為02021/3/119 Sockaddr_in Sockaddr_in 格式格式(IPv4(IPv4用用) )struct sockaddr_in { short sin_family;u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; };sin_family:位址資料族系,同樣設定為AF_INETsin_port:主機開啟的通訊埠號 用htons() 寫入sin_addr:主機IP位址 in_addr資料格式sin_zero[8]:目前沒用處,保留以後使用2021/3/1110 in_addrin_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對此變數寫入便可函式庫引入的標頭檔應該會有定義#define s_addr S_un.s_addr此後只要對前一頁之變數sin_addr.s_addr存取便可寫入時使用inet_addr(“IP位址字串”)轉換成unsigned long2021/3/1111 範例SOCKET Sock; sockaddr_in saServer; Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 設定本機通訊用的位址saServer.sin_family = AF_INET; saServer.sin_port = htons(5150);//啟用5150 portsaServer.sin_addr.s_addr = inet_addr(“140.115.65.30”); //設定本機IP// 呼叫Bind函式 bind(Sock,(SOCKADDR*) &saServer, sizeof(saServer) ); 2021/3/1112 ListenListen函式函式 設定設定socketsocket等待外部連線等待外部連線 listen()是使Socket進入等待連線狀態,等待客戶端(Client) 連上線來,很顯然的呼叫此函式的主機,功能會是一台伺服器(Server)。

      如果有Client想要連過來,此時可以呼叫connect()來跟Server 連線而Server接受後會建立新的socket和Client通訊,listen socket則繼續存在等待其他Client,直到關閉為止2021/3/1113 listen()listen()函式函式int listen( SOCKET s, int backlog ); s:設定好bind(),並且尚未連線的socketBacklog:等待Server接受連線前,同時最大連線數回傳值:-1表錯誤,否則為02021/3/1114 AcceptAccept函式函式 接受外部連線Blocking Non-blocking2021/3/1115 Accept() Accept() 函式函式SOCKET accept( SOCKET s, struct sockaddr* addr, int* addrlen ); s:一個設定為listen狀態的socketsddr:Client端位址資訊,由函式自動產生填入addrlen:sddr長度,由函式自動產生回傳值:-1表示錯誤,否則傳回另一個包含Client端資訊的新socket descriptor,作為傳送資料用傳進accept()的listen socket本身並沒有辦法作資料的傳輸,所以必須透過accept()產生一個包含通訊協定、Server、Client資訊的新socket,利用他就可以進行資料的傳輸了2021/3/1116 範例ListenSocket 為一個bind()過且未連線的socket// 設定socket為接聽外部連線用if (listen( ListenSocket, 1 ) == SOCKET_ERROR) printf("Error listening on socket.\n"); // 宣告一個用來和Client連線用的socket SOCKET AcceptSocket; // 接受外部連線while(1) { AcceptSocket = SOCKET_ERROR; //尚未取得socket descriptor,等待外部連線進入時重設while( AcceptSocket == SOCKET_ERROR ) { AcceptSocket = accept( ListenSocket, NULL, NULL ); } printf("Client connected.\n"); break; } 2021/3/1117 connect函式 與等待接聽的socket連線Client端若要與Server溝通,必須透過connect建立連線,經過驗證確定連線成功後,才能進行資料傳輸。

      三向交握(three-way handshake)機制:1.Client向Server提出連線要求(connect())2.Server若接到要求,則回應Clinet接到要求3.Client接到回應,向Server表示收到回覆至此才算連線建立完成,雙方可以開始交換資料若發生錯誤,則會由轉送中繼站回傳ICMP錯誤訊息connect函式讀到後,會回報錯誤給程式2021/3/1118 connect()connect()函式函式int connect( SOCKET s, const struct sockaddr* name, int namelen ); 設定方式請參照bind()函式name內資料為回傳值:-1表錯誤,否則回傳02021/3/1119 recv(),send()recv(),send()函式函式 處理資料收送處理資料收送從先前設定好Server與Client的通訊方式後,我們利用進行資料交換的函式recv(),send()來處理要溝通的資料,其實資料溝通的函式有許多種類,read(),write(),readv(),writev(),recvmsg(),sendmsg()等等,我們介紹recv()和send()給大家入門,其他函式的使用可以查閱MSDN或 man 說明文件2021/3/1120 recv() recv() 函式函式int recv( SOCKET s, char* buf, int len, int flags ); s:一個建立連線成功的socketbuf:呼叫recv,用來儲存收到資料的暫存器len:buf的長度(byte)flags:選擇工作模式,一般填入0回傳值:-1表錯誤,否則傳回接受到資料的長度(byte)2021/3/1121 send()send()函式函式int send( SOCKET s, const char* buf, int len, int flags); s:一個建立連線成功的socketbuf:用來儲存將送出資料的暫存器len:buf的長度(byte)flags:選擇工作模式,一般填入0回傳值:-1表錯誤,否則傳回送出資料的長度(byte)2021/3/1122 範例範例//Server端int bytesSent; int bytesRecv = SOCKET_ERROR; char sendbuf[32] = "Server: Sending Data."; char recvbuf[32] = ""; bytesRecv = recv( m_socket, recvbuf, 32, 0 ); printf( "Bytes Recv: %ld\n", bytesRecv ); bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 ); printf( "Bytes Sent: %ld\n", bytesSent ); //Client端int bytesSent; int bytesRecv = SOCKET_ERROR; char sendbuf[32] = "Client: Sending data."; char recvbuf[32] = ""; bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 ); printf( "Bytes Sent: %ld\n", bytesSent ); while( bytesRecv == 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: %ld\n", bytesRecv ); } 2021/3/1123 closesocket(),shutdown()closesocket(),shutdown()函式函式 中斷連線中斷連線在accept()或connect()成功後建立的通訊用socket,必須由Client或Server下達closesocket()或shutdown()來結束連線。

      closesocket()可以用來終止TCP連線,但不會馬上關閉,必須等到該socket不在動作後才切斷連線,這和TCP協定中使用到的sliding window有關,這是用完再關的函式,而shutdown()是有強制性質的中斷連線函式,用來控制socket的IO一個好的中斷連線作法應有四步:1.結束傳送資料2.使用shutdown(),設定為禁止送出資料3.呼叫recv(),確定收到的資料長度為0,避免遺漏資訊4.closesocket() 來關閉socket註:在Winsock中使用的closesocket()和BSD socket中的close()是相同的2021/3/1124 closesocket() closesocket() 與與 shutdown() shutdown()函式函式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表錯誤,否則傳回02021/3/1125 Server-Client Modelrecv() send()2021/3/1126 WINSOCKETSp#include 2021/3/1127 WINSOCKETSpWSADATA wsadata;pif (WSAStartup(0x101,(LPWSADATA) &wsadata) != 0) { fprintf(stderr,"echo_srv: can't use WinSock DLL\n");exit(1); }2021/3/1128 WINSOCKETSpWSACleanup();2021/3/1129 Server端用到的元件pListBox – 顯示項目清單可以利用 ListBox1->Items->Add()新增資料或是ListBox1->Items->Insert()插入資料Add(字串), Insert(位置,字串)由於本次Server端只用到這一個元件,直接拉到滿版…2021/3/1130 Server端用到的元件pTimer – 計時器等待,定時輪詢2021/3/1131 Server端用到的語法p#define A B 定義A為B,如利用#define Add(Text) ListBox1->Items->Insert(0,Text)這樣就可以用簡短的Add(“文字”)指令取代一長串的Insert指令p註:#define只會增加編譯時間(要轉換),對於程式的實際效能毫無影響2021/3/1132 Server端的工作流程p程式啟動直接開始監聽工作WSAStartupsocketbindlistenp程式結束時關閉連線shutdownclosesocket2021/3/1133 Server端的工作流程p用Timer做定時監測若已經連線 {recv接收資料} 否則 {accept 接受連線}p!accept & recv 在沒有資料進入(沒人連線或沒有資料)時會阻塞住導致程式停止回應2021/3/1134 Server停止回應的處理方法p1. 用非阻塞式函數WSAAcceptExWSARecvWaitForSingleObjectp2. 多執行緒p3. 中斷法2021/3/1135 个人观点供参考,欢迎讨论 。

      点击阅读更多内容
      相关文档
      2025国开山东开大《土质学与土力学》形成性考核123答案+终结性考核答案.docx 中学综合素质知识点梳理【中学教师资格证】.docx 2025国开山东开大《特许经营概论》形成性考核123答案+终结性考核答案.doc 2025年高考英语全国一卷真题(含答案).docx 2025国开山东《农民专业合作社创建与管理》形成性考核123答案+终结性考核答案.docx 2025国开山东开大《自然现象探秘》形成性考核123答案+终结性考核答案.docx 2025国开山东《消费心理学》形成性考核123答案+终结性考核答案.doc 2025国开山东《小微企业管理》形成性考核123答案+终结性考核答案.doc 2025国开山东开大《资本经营》形成性考核123答案+终结性考试答案.docx 2025国开山东《小学生心理健康教育》形考123答案+终结性考试答案.docx 2025国开《视频策划与制作》形考任务1-4答案.docx 2025国开《亲子关系与亲子沟通》形考任务234答案+期末大作业答案.docx 2025国开电大《煤矿地质》形成性考核123答案.docx 2025国开电大《冶金原理》形考任务1234答案.docx 2025国开《在线学习项目运营与管理》形考任务1234答案.doc 2025国开电大《在线教育的理论与实践》阶段测验1-4答案.docx 2024 年注册环保工程师《专业基础考试》真题及答案解析【完整版】.docx 环保工程师---2023 年注册环保工程师《专业基础考试》真题及答案解析【完整版】.docx 2025国开《液压与气压传动》形考任务一参考答案.docx 2025年春江苏开放大学教育研究方法060616计分:形成性作业2、3答案.docx
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.