国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

14.1 Socket 套接字編程入門

這篇具有很好參考價值的文章主要介紹了14.1 Socket 套接字編程入門。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Winsock是Windows操作系統(tǒng)上的套接字API,用于在網(wǎng)絡上進行數(shù)據(jù)通信。套接字通信是一種允許應用程序在計算機網(wǎng)絡上進行實時數(shù)據(jù)交換的技術(shù)。通過使用Windows提供的API,應用程序可以創(chuàng)建一個套接字來進行數(shù)據(jù)通信。這個套接字可以綁定到一個端口,以允許其他應用程序連接它。另外,Winsock可以使用TCP/IP、UDP等協(xié)議來完成不同類型的數(shù)據(jù)傳輸任務。在網(wǎng)絡應用程序開發(fā)中,套接字通信可以幫助應用程序開發(fā)者實現(xiàn)客戶端/服務端模型,并實現(xiàn)數(shù)據(jù)的可靠傳輸。

一般套接字通信需要經(jīng)歷,創(chuàng)建套接字(Socket),綁定(Bind),監(jiān)聽(Listen),接受(Accept),連接(Connect),發(fā)送數(shù)據(jù)(Send),接收數(shù)據(jù)(Receive),關(guān)閉(Close)等幾個關(guān)鍵步驟,當讀者需要使用網(wǎng)絡通信時需引入winsock2.h頭文件,并通過#pragma comment(lib,"ws2_32.lib")包含對應庫,需要注意的是該頭文件與windows.h頭沖突,如果兩者同時存在則會出現(xiàn)編譯不通過的情況;

14.1.1 服務端通信

(1)WSAStartup(MAKEWORD(2, 0), &WSAData)

當讀者需要使用套接字編程時,不論是服務端還是客戶端都需要調(diào)用WSAStartup初始化套接字庫,該函數(shù)接受兩個參數(shù)傳遞,第一個參數(shù)一般默認會傳遞MAKEWORD(2, 0) 它是一個宏,用于將兩個8位的字節(jié)合并成一個16位的字,在MAKEWORD(2, 0)中,括號內(nèi)的數(shù)字分別代表高位字節(jié)(2)和低位字節(jié)(0),宏會將它們合并成一個16位的無符號short整型數(shù)據(jù),即0000001000000000(二進制),表示Winsock的版本號為2.0。第二個參數(shù)WSADATA結(jié)構(gòu)體,用于Winsock初始化時存儲相關(guān)的信息,一般會在全局WSADATA WSAData;直接定義得到。

#include <iostream>
#include <winsock2.h>
#include <WS2tcpip.h>

#pragma comment(lib,"ws2_32.lib")

// 定義結(jié)構(gòu)體
WSADATA WSAData;

// 啟動winsock中的WSAStartup()函數(shù)對Winsock DLL進行初始化
if (WSAStartup(MAKEWORD(2, 0), &WSAData) == SOCKET_ERROR)
{
    std::cout << "WSA動態(tài)庫初始化失敗" << std::endl;
    return 0;
}

(2)socket(AF_INET, SOCK_STREAM, 0)

通信的第二步則是調(diào)用Socket()函數(shù),該函數(shù)是用于創(chuàng)建一個套接字的系統(tǒng)調(diào)用。在該函數(shù)中,給定三個參數(shù),分別為地址族(Address Family)、套接字類型(Socket Type)和協(xié)議(Protocol),套接字在初始化并完成時會返回一個SOCKET類型的文件描述符句柄,此處我們將該句柄存儲至server_socket變量內(nèi)。AF_INET用于指定套接字地址族為IPv4類型,SOCK_STREAM則用于指定該套接字的類型為流式套接字,用于面向連接的可靠數(shù)據(jù)傳輸(TCP協(xié)議)。

// 服務進程創(chuàng)建套接字句柄(用于監(jiān)聽)
SOCKET server_socket;

// 調(diào)用socket()函數(shù)創(chuàng)建一個流套接字,參數(shù)(網(wǎng)絡地址類型,套接字類型,網(wǎng)絡協(xié)議)
if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == ERROR)
{
  std::cout << "Socket 創(chuàng)建失敗" << std::endl;
  WSACleanup();
  return 0;
}

(3)bind(server_socket, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr))

套接字編程的第三步則是綁定,套接字的綁定需要調(diào)用bind()函數(shù)實現(xiàn),該函數(shù)接受三個參數(shù)傳遞,第一個參數(shù)是socket()中創(chuàng)建的套接字文件描述符句柄,該參數(shù)用于指定針對哪一個套接字進行操作,第二個參數(shù)則是sockaddr_in類型的結(jié)構(gòu)體,該結(jié)構(gòu)體內(nèi)用于指定需要綁定套接字的具體類型參數(shù)等信息,在如下代碼中我們通過ServerAddr.sin_family = AF_INET;將套接字類型設(shè)置為了互聯(lián)網(wǎng)域模式,通過ServerAddr.sin_port = htons(9999);指定了需要綁定的端口號,而ServerAddr.sin_addr.s_addr = inet_addr("0.0.0.0");則用于指定了要綁定本機的那個網(wǎng)口,一般而言如果讀者需要在本機使用此處可填入127.0.0.1而如果偵聽任意一個網(wǎng)口則可使用0.0.0.0,第三個參數(shù)則是傳入結(jié)構(gòu)體的長度,此處通過sizeof(ServerAddr)方法得到,最終將結(jié)構(gòu)體ServerAddr直接填入綁定函數(shù)即可實現(xiàn)對網(wǎng)絡套接字的綁定。

// 結(jié)構(gòu)sockaddr_in用來標識TCP/IP協(xié)議下的地址,可強制轉(zhuǎn)換為sockaddr結(jié)構(gòu)
struct sockaddr_in ServerAddr;

// 字段sin_family必須設(shè)為AF_INET,表示該Socket處于Internet域
ServerAddr.sin_family = AF_INET;

// 字段sin_port用于指定服務端口,注意避免沖突
ServerAddr.sin_port = htons(9999);

// 字段sin_addr用于把一個IP地址保存為一個4字節(jié),無符號長整型,根據(jù)不同用法還可表示本地或遠程IP地址
// 該字段可以直接使用INADDR_ANY代表偵聽所有地址,也可指定地址
ServerAddr.sin_addr.s_addr = inet_addr("0.0.0.0");

// 調(diào)用bind()函數(shù)將本地地址綁定到所創(chuàng)建的套接字上,以在網(wǎng)絡上標識該套接字
if (bind(server_socket, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
  std::cout << "綁定套接字失敗" << std::endl;
  closesocket(server_socket);
  WSACleanup();
  return 0;
}

(4)listen(server_socket, 10)

當套接字被綁定后,接下來則是偵聽套接字,通過調(diào)用listen()函數(shù)將套接字置入監(jiān)聽模式并準備接受連接請求,該函數(shù)需要傳入兩個參數(shù),參數(shù)1為套接字套接字句柄,參數(shù)二為偵聽套接字最大連接數(shù),如果進入偵聽狀態(tài)則說明該套接字是等待連接狀態(tài),一旦服務器接受了連接,它可以使用返回的套接字對象與發(fā)起連接的客戶端進行通信。

// 將 ServerAddr.sin_addr 網(wǎng)絡字節(jié)序,轉(zhuǎn)為本機偵聽IP地址
char local_address[20];
inet_ntop(AF_INET, &ServerAddr.sin_addr, local_address, 16);
std::cout << "偵聽本地地址: " << local_address << " 偵聽本地端口: " << ntohs(ServerAddr.sin_port) << std::endl;

// 參數(shù)(已捆綁未連接的套接字描述字,正在等待連接的最大隊列長度)
if (listen(server_socket, 10) == SOCKET_ERROR)
{
  std::cout << "偵聽套接字失敗" << std::endl;
  closesocket(server_socket);
  WSACleanup();
  return 0;
}

(5)accept(server_socket, (LPSOCKADDR)0, (int*)0)

當一個套接字進入偵聽狀態(tài)后則下一步是需要等待有客戶端連接到本端,當服務器通過調(diào)用listen()函數(shù)開始監(jiān)聽連接請求時,客戶端可以通過使用connect()函數(shù)嘗試與服務器建立連接。一旦客戶端發(fā)送連接請求,服務器將收到通知。然后服務器可以使用accept()函數(shù)接受連接請求并創(chuàng)建一個新的套接字對象,該對象可以用于與客戶端進行通信。

accept() 函數(shù)通常在一個循環(huán)中使用,以便服務器可以在等待新連接時繼續(xù)處理已連接的客戶端。每次調(diào)用accept()函數(shù)時,如果有連接請求,則函數(shù)將阻塞直到一個連接請求被接受。一旦連接請求被接受,函數(shù)將返回一個新的套接字對象和客戶端的地址信息。

在接受連接請求并創(chuàng)建新的套接字對象之后,服務器可以使用該對象與客戶端進行通信。同時,服務器可以使用原始的server_socket套接字對象來等待更多的連接請求,以便能夠接受更多的客戶端連接。

如下的代碼中當accept()接收到等待消息時,則會將該句柄保存至message_socket變量內(nèi),此時用戶只需要向該指針中發(fā)送recv()或接收send()數(shù)據(jù)即可,此時套接字通信即可正式被建立起來。

// 數(shù)據(jù)接收緩沖區(qū)
SOCKET message_socket;
char buf[8192] = {0};
while (1)
{
  // 進入監(jiān)聽狀態(tài)后,調(diào)用accept()函數(shù)接收客戶端的連接請求,并把連接傳給msgsock套接字
  // 原sock套接字繼續(xù)監(jiān)聽其他客戶機連接請求
  if ((message_socket = accept(server_socket, (LPSOCKADDR)0, (int*)0)) == INVALID_SOCKET)
  {
    continue;
  }

  // 初始化數(shù)據(jù)接收緩沖區(qū)
  memset(buf, 0, sizeof(buf));
   
  // 接收客戶端發(fā)送過來的數(shù)據(jù)
  bool ref = recv(message_socket, buf, 8192, 0);
  if (ref != 0)
  {
    std::cout << "接收數(shù)據(jù): " << buf << std::endl;
  }
  
  // 關(guān)閉子套接字
  closesocket(message_socket);
}

至此我們的服務端將被運行起來,需要注意的是服務端程序如果需要結(jié)束本次會話則需要手動調(diào)用closesocket(server_socket);關(guān)閉一個套接字句柄,當整個進程執(zhí)行結(jié)束后讀者還需要調(diào)用WSACleanup()終止對Winsock DLL的使用,并釋放資源。

14.1.2 客戶端通信

對于客戶端通信而言其流程與服務端通信基本保持一致,該流程分別是,創(chuàng)建套接字,連接到服務器,建立連接,發(fā)送數(shù)據(jù),關(guān)閉連接,對于初始化部分客戶端通信與服務端沒有任何區(qū)別,唯一的區(qū)別在于對于服務端而言一般是使用listen()函數(shù)偵聽套接字,而對于客戶端而言則是使用connect()函數(shù)連接到服務端,一旦連接建立成功,客戶端可以通過向服務器發(fā)送數(shù)據(jù)來與服務器進行通信。

在調(diào)用connect(socket_addr)時,需要傳遞一個參數(shù)sockaddr。sockaddr 是一個結(jié)構(gòu)體,包含了客戶端與服務器的地址信息,包括其IP地址和端口號。在C/C++中,sockaddr 結(jié)構(gòu)體通常被定義為sockaddr_in結(jié)構(gòu)體,包含了IP地址和端口號等信息。如果連接建立成功,connect() 函數(shù)將返回 0。如果連接失敗,則會返回一個錯誤代碼,其中最常見的錯誤是連接超時或目標主機拒絕連接。

一旦連接建立成功,客戶端可以使用新創(chuàng)建的套接字對象向服務器發(fā)送數(shù)據(jù),并使用recv()函數(shù)從服務器接收數(shù)據(jù)。一般來說,在與服務器進行通信之前,客戶端套接字需要使用bind()函數(shù)指定一個本地地址和端口,以確保數(shù)據(jù)可以正確地傳輸。

int main(int argc, char* argv[])
{
  char buf[8192] = { 0 };

  while (1)
  {
    std::cout << "發(fā)送數(shù)據(jù): ";
    int inputLen = 0;
    memset(buf, 0, sizeof(buf));

    // 輸入以回車鍵為結(jié)束標識
    while ((buf[inputLen++] = getchar()) != '\n'){ ; }

    // 初始化
    WSADATA WSAData;
    if (WSAStartup(MAKEWORD(2, 0), &WSAData) == SOCKET_ERROR)
    {
      continue;
    }

    // 創(chuàng)建套接字
    SOCKET client_socket;
    if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
    {
      WSACleanup();
      continue;
    }

    // 填充通信結(jié)構(gòu)體
    struct sockaddr_in ClientAddr;
    ClientAddr.sin_family = AF_INET;
    ClientAddr.sin_port = htons(9999);
    ClientAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    // 連接到服務端
    if (connect(client_socket, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr)) == SOCKET_ERROR)
    {
      closesocket(client_socket);
      WSACleanup();
      continue;
    }

    // 向服務端發(fā)送數(shù)據(jù)
    send(client_socket, buf, 8192, 0);

    // 關(guān)閉套接字
    closesocket(client_socket);
    WSACleanup();
  }

  return 0;
}

讀者可自行運行上述程序,啟動服務端與客戶端,并發(fā)送測試數(shù)據(jù)觀察變化,當發(fā)送數(shù)據(jù)后讀者應該能看到如下圖所示的提示信息;

14.1 Socket 套接字編程入門文章來源地址http://www.zghlxwxcb.cn/news/detail-710596.html

到了這里,關(guān)于14.1 Socket 套接字編程入門的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • 網(wǎng)絡編程套接字(Socket)

    網(wǎng)絡編程套接字(Socket)

    認識IP地址, 端口號, 網(wǎng)絡字節(jié)序等網(wǎng)絡編程中的基本概念; 學習socket api的基本用法; 能夠?qū)崿F(xiàn)一個簡單的udp客戶端/服務器; 能夠?qū)崿F(xiàn)一個簡單的tcp客戶端/服務器(單連接版本, 多進程版本, 多線程版本); 理解tcp服務器建立連接, 發(fā)送數(shù)據(jù), 斷開連接的流程; 通俗易懂地說,源

    2024年01月21日
    瀏覽(106)
  • 網(wǎng)絡編程—Socket套接字詳解

    網(wǎng)絡編程—Socket套接字詳解

    目錄 一、網(wǎng)絡編程 1.1、為什么需要網(wǎng)絡編程? 1.2、什么是網(wǎng)絡編程 1.3、發(fā)送端和接收端 ?編輯1.4、請求和響應 ?編輯1.5、客戶端和服務端? 二、Socket套接字? 2.1、概念 2.2、分類? 2.2.1、流套接字? 2.2.2、數(shù)據(jù)報套接字? 2.2.3、原始套接字? 2.3、Socket編程注意事項? 1.1、為什

    2024年02月16日
    瀏覽(101)
  • 【Linux】socket 編程(socket套接字介紹、字節(jié)序、socket地址、IP地址轉(zhuǎn)換函數(shù)、套接字函數(shù)、TCP通信實現(xiàn))

    【Linux】socket 編程(socket套接字介紹、字節(jié)序、socket地址、IP地址轉(zhuǎn)換函數(shù)、套接字函數(shù)、TCP通信實現(xiàn))

    橙色 所謂套接字,就是對網(wǎng)絡中不同主機上的應用進程之間進行雙向通信的端點的抽象。 一個套接字就是網(wǎng)絡上進程通信的一端,提供了應用層進程利用網(wǎng)絡協(xié)議交換數(shù)據(jù)的機制。從所處的地位來講,套接字上聯(lián)應用進程,下聯(lián)網(wǎng)絡協(xié)議棧,是應用程序通過網(wǎng)絡協(xié)議進程通

    2024年02月09日
    瀏覽(19)
  • [JAVAee]網(wǎng)絡編程-套接字Socket

    [JAVAee]網(wǎng)絡編程-套接字Socket

    目錄 基本概念 發(fā)送端與接收端 請求與響應 ?編輯客戶端與服務器 Socket套接字? 分類 數(shù)據(jù)報套接字 流套接字傳輸模型?? UDP數(shù)據(jù)報套接字編程 DatagramSocket API DatagramPacket API InetSocketAddress API 示例一: 示例二: TCP流數(shù)據(jù)報套接字編程 ServerSocket API Socket API 示例一: ? 網(wǎng)絡編程指的

    2024年02月13日
    瀏覽(126)
  • 網(wǎng)絡編程之 Socket 套接字(使用數(shù)據(jù)報套接字和流套接字分別實現(xiàn)一個小程序(附源碼))

    網(wǎng)絡編程之 Socket 套接字(使用數(shù)據(jù)報套接字和流套接字分別實現(xiàn)一個小程序(附源碼))

    網(wǎng)絡編程是指網(wǎng)絡上的主機,通過不同的進程,以編程的方式實現(xiàn) 網(wǎng)絡通信(或稱為網(wǎng)絡數(shù)據(jù)傳輸) 只要滿足不同的進程就可以進行通信,所以即便是在同一個主機,只要不同的進程,基于網(wǎng)絡傳輸數(shù)據(jù),也屬于網(wǎng)絡編程 在一次網(wǎng)絡傳輸中: 發(fā)送端: 數(shù)據(jù)的 發(fā)送方進程

    2024年02月03日
    瀏覽(85)
  • 【網(wǎng)絡編程】網(wǎng)絡編程 和 Socket 套接字認識

    【網(wǎng)絡編程】網(wǎng)絡編程 和 Socket 套接字認識

    ?個人主頁:bit me?? ?當前專欄:Java EE初階?? 用戶在瀏覽器中,打開在線視頻網(wǎng)站,如優(yōu)酷看視頻,實質(zhì)是通過網(wǎng)絡,獲取到網(wǎng)絡上的一個視頻資源。 與本地打開視頻文件類似,只是視頻文件這個資源的來源是網(wǎng)絡。 相比本地資源來說,網(wǎng)絡提供了更為豐富的網(wǎng)絡資源:

    2023年04月15日
    瀏覽(516)
  • 【網(wǎng)絡通信】socket編程——TCP套接字

    【網(wǎng)絡通信】socket編程——TCP套接字

    TCP依舊使用代碼來熟悉對應的套接字,很多接口都是在udp中使用過的 所以就不會單獨把他們拿出來作為標題了,只會把第一次出現(xiàn)的接口作為標題 通過TCP的套接字 ,來把數(shù)據(jù)交付給對方的應用層,完成雙方進程的通信 在 tcpServer.hpp 中,創(chuàng)建一個命名空間 yzq 用于封裝 在命名

    2024年02月13日
    瀏覽(102)
  • 「網(wǎng)絡編程」第二講:網(wǎng)絡編程socket套接字(一)

    「網(wǎng)絡編程」第二講:網(wǎng)絡編程socket套接字(一)

    「前言」文章是關(guān)于網(wǎng)絡編程的socket套接字方面的,下面開始講解! 「歸屬專欄」網(wǎng)絡編程 「主頁鏈接」個人主頁 「筆者」楓葉先生(fy) 「楓葉先生有點文青病」「每篇一句」 春風得意馬蹄疾,一日看盡長安花。 ——孟郊《登科后》 目錄 一、預備知識 1.1 源IP和目的IP 1.

    2024年02月09日
    瀏覽(87)
  • 【JavaEE初階】 網(wǎng)絡編程基礎(chǔ)與Socket套接字

    【JavaEE初階】 網(wǎng)絡編程基礎(chǔ)與Socket套接字

    用戶在瀏覽器中,打開在線視頻網(wǎng)站,如騰訊看視頻,實質(zhì)是通過網(wǎng)絡,獲取到網(wǎng)絡上的一個視頻資源。 與本地打開視頻文件類似,只是視頻文件這個資源的來源是 網(wǎng)絡 。 相比本地資源來說,網(wǎng)絡提供了更為豐富的網(wǎng)絡資源: 所謂的網(wǎng)絡資源,其實就是在網(wǎng)絡中可以獲取

    2024年02月05日
    瀏覽(97)
  • Linux網(wǎng)絡編程- 原始套接字(Raw Socket)

    原始套接字(Raw Socket)提供了一種機制,允許應用程序直接訪問底層傳輸協(xié)議,繞過操作系統(tǒng)提供的傳輸層接口。這種套接字通常用于實現(xiàn)新的協(xié)議或?qū)ΜF(xiàn)有協(xié)議進行低級別的操作。 以下是對原始套接字的詳細介紹: 定義與用途 : 原始套接字是直接基于網(wǎng)絡層(如IP)的。

    2024年02月07日
    瀏覽(97)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包