最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TCP與UDP協(xié)議的Socket編程詳解(附詳細(xì)示例)

 更新時(shí)間:2025年08月23日 09:11:58   作者:bkspiderx  
scoket編程即套接字編程,是網(wǎng)絡(luò)編程的基礎(chǔ),它允許兩臺(tái)或者多臺(tái)計(jì)算機(jī)進(jìn)行網(wǎng)絡(luò)通信,這篇文章主要介紹了TCP與UDP協(xié)議的Socket編程的相關(guān)資料,需要的朋友可以參考下

前言

在網(wǎng)絡(luò)通信中,Socket是實(shí)現(xiàn)不同主機(jī)間進(jìn)程通信的核心接口。TCP和UDP作為傳輸層的兩大核心協(xié)議,其Socket編程方式因協(xié)議特性差異而有所不同。本文將詳細(xì)介紹兩種協(xié)議的Socket編程流程、實(shí)現(xiàn)示例及核心差異。

一、TCP協(xié)議的Socket編程

TCP(傳輸控制協(xié)議)是面向連接的可靠傳輸協(xié)議,其Socket編程需遵循"建立連接-數(shù)據(jù)傳輸-釋放連接"的流程,類(lèi)似現(xiàn)實(shí)中的"打電話(huà)"場(chǎng)景。

1. 核心流程

服務(wù)器端流程:

  1. 創(chuàng)建Socket:生成用于通信的文件描述符,指定協(xié)議族和套接字類(lèi)型。
  2. 綁定地址:將Socket與特定IP地址和端口綁定,確定通信端點(diǎn)。
  3. 監(jiān)聽(tīng)連接:進(jìn)入被動(dòng)監(jiān)聽(tīng)狀態(tài),等待客戶(hù)端連接請(qǐng)求。
  4. 接受連接:從等待隊(duì)列中取出客戶(hù)端連接,創(chuàng)建新的Socket用于數(shù)據(jù)傳輸。
  5. 收發(fā)數(shù)據(jù):通過(guò)新Socket與客戶(hù)端進(jìn)行雙向數(shù)據(jù)交互。
  6. 關(guān)閉連接:通信結(jié)束后,關(guān)閉Socket釋放資源。

客戶(hù)端流程:

  1. 創(chuàng)建Socket:生成與服務(wù)器通信的Socket。
  2. 發(fā)起連接:向服務(wù)器的IP和端口發(fā)送連接請(qǐng)求。
  3. 收發(fā)數(shù)據(jù):連接建立后,與服務(wù)器進(jìn)行數(shù)據(jù)交互。
  4. 關(guān)閉連接:通信結(jié)束后,關(guān)閉Socket。

2. TCP Socket編程示例

服務(wù)器端代碼(C語(yǔ)言):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[BUFFER_SIZE] = {0};
    const char *response = "Hello from TCP server";

    // 1. 創(chuàng)建TCP套接字(SOCK_STREAM表示流式套接字)
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 設(shè)置套接字選項(xiàng),允許端口復(fù)用
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    
    // 配置地址信息(IPv4、任意本地IP、端口8080)
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // 2. 綁定套接字到指定端口
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 3. 監(jiān)聽(tīng)連接請(qǐng)求(最大等待隊(duì)列長(zhǎng)度為5)
    if (listen(server_fd, 5) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    
    printf("TCP Server listening on port %d...\n", PORT);

    // 4. 接受客戶(hù)端連接(阻塞等待)
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    // 5. 讀取客戶(hù)端數(shù)據(jù)
    ssize_t valread = read(new_socket, buffer, BUFFER_SIZE);
    printf("Received from client: %s\n", buffer);

    // 向客戶(hù)端發(fā)送響應(yīng)
    send(new_socket, response, strlen(response), 0);
    printf("Response sent to client\n");

    // 6. 關(guān)閉連接
    close(new_socket);
    close(server_fd);
    return 0;
}

客戶(hù)端代碼(C語(yǔ)言):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sock = 0;
    struct sockaddr_in serv_addr;
    char buffer[BUFFER_SIZE] = {0};
    const char *message = "Hello from TCP client";

    // 1. 創(chuàng)建TCP套接字
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("\nSocket creation error\n");
        return -1;
    }

    // 配置服務(wù)器地址信息
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // 轉(zhuǎn)換IP地址(字符串轉(zhuǎn)二進(jìn)制)
    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
        printf("\nInvalid address/ Address not supported\n");
        return -1;
    }

    // 2. 連接服務(wù)器(三次握手在此過(guò)程完成)
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        printf("\nConnection failed\n");
        return -1;
    }

    // 3. 向服務(wù)器發(fā)送數(shù)據(jù)
    send(sock, message, strlen(message), 0);
    printf("Message sent to server\n");

    // 接收服務(wù)器響應(yīng)
    ssize_t valread = read(sock, buffer, BUFFER_SIZE);
    printf("Received from server: %s\n", buffer);

    // 4. 關(guān)閉連接
    close(sock);
    return 0;
}

二、UDP協(xié)議的Socket編程

UDP(用戶(hù)數(shù)據(jù)報(bào)協(xié)議)是無(wú)連接的不可靠傳輸協(xié)議,其Socket編程無(wú)需建立連接,直接發(fā)送數(shù)據(jù)報(bào),類(lèi)似現(xiàn)實(shí)中的"寄明信片"場(chǎng)景。

1. 核心流程

服務(wù)器端流程:

  1. 創(chuàng)建Socket:生成數(shù)據(jù)報(bào)套接字。
  2. 綁定地址:將Socket與特定IP和端口綁定。
  3. 收發(fā)數(shù)據(jù):通過(guò)recvfrom()接收客戶(hù)端數(shù)據(jù)(含客戶(hù)端地址),通過(guò)sendto()向客戶(hù)端發(fā)送響應(yīng)。
  4. 關(guān)閉Socket:通信結(jié)束后釋放資源。

客戶(hù)端流程:

  1. 創(chuàng)建Socket:生成數(shù)據(jù)報(bào)套接字。
  2. 收發(fā)數(shù)據(jù):通過(guò)sendto()向服務(wù)器發(fā)送數(shù)據(jù)(指定服務(wù)器地址),通過(guò)recvfrom()接收服務(wù)器響應(yīng)。
  3. 關(guān)閉Socket:通信結(jié)束后釋放資源。

2. UDP Socket編程示例

服務(wù)器端代碼(C語(yǔ)言):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sockfd;
    char buffer[BUFFER_SIZE];
    struct sockaddr_in servaddr, cliaddr;
    const char *response = "Hello from UDP server";

    // 1. 創(chuàng)建UDP套接字(SOCK_DGRAM表示數(shù)據(jù)報(bào)套接字)
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0, sizeof(servaddr));
    memset(&cliaddr, 0, sizeof(cliaddr));

    // 配置服務(wù)器地址信息
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);

    // 2. 綁定套接字到指定端口
    if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    printf("UDP Server listening on port %d...\n", PORT);

    socklen_t len = sizeof(cliaddr);

    // 3. 接收客戶(hù)端數(shù)據(jù)報(bào)(阻塞等待,同時(shí)獲取客戶(hù)端地址)
    ssize_t n = recvfrom(sockfd, (char *)buffer, BUFFER_SIZE, MSG_WAITALL, 
                        (struct sockaddr *)&cliaddr, &len);
    buffer[n] = '\0';
    printf("Received from client: %s\n", buffer);

    // 向客戶(hù)端發(fā)送響應(yīng)(需指定客戶(hù)端地址)
    sendto(sockfd, (const char *)response, strlen(response), 
           MSG_CONFIRM, (const struct sockaddr *)&cliaddr, len);
    printf("Response sent to client\n");

    // 4. 關(guān)閉套接字
    close(sockfd);
    return 0;
}

客戶(hù)端代碼(C語(yǔ)言):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sockfd;
    char buffer[BUFFER_SIZE];
    struct sockaddr_in servaddr;
    const char *message = "Hello from UDP client";

    // 1. 創(chuàng)建UDP套接字
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0, sizeof(servaddr));

    // 配置服務(wù)器地址信息
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    socklen_t len = sizeof(servaddr);

    // 2. 向服務(wù)器發(fā)送數(shù)據(jù)報(bào)(需指定服務(wù)器地址)
    sendto(sockfd, (const char *)message, strlen(message), 
           MSG_CONFIRM, (const struct sockaddr *)&servaddr, sizeof(servaddr));
    printf("Message sent to server\n");

    // 接收服務(wù)器響應(yīng)
    ssize_t n = recvfrom(sockfd, (char *)buffer, BUFFER_SIZE, 
                        MSG_WAITALL, (struct sockaddr *)&servaddr, &len);
    buffer[n] = '\0';
    printf("Received from server: %s\n", buffer);

    // 3. 關(guān)閉套接字
    close(sockfd);
    return 0;
}

三、TCP與UDP Socket編程的核心差異

對(duì)比維度TCP Socket編程UDP Socket編程
套接字類(lèi)型使用SOCK_STREAM(流式套接字)使用SOCK_DGRAM(數(shù)據(jù)報(bào)套接字)
連接處理connect()(客戶(hù)端)和accept()(服務(wù)器)建立連接無(wú)需建立連接,直接傳輸數(shù)據(jù)
數(shù)據(jù)傳輸函數(shù)使用read()/write()send()/recv()使用sendto()/recvfrom()(需指定地址)
地址關(guān)聯(lián)連接建立后自動(dòng)關(guān)聯(lián)地址,無(wú)需重復(fù)指定每次傳輸都需顯式指定目標(biāo)地址
可靠性保障協(xié)議層保證可靠傳輸,編程無(wú)需處理丟失重傳需手動(dòng)實(shí)現(xiàn)重傳、排序等可靠性機(jī)制
服務(wù)器并發(fā)需為每個(gè)客戶(hù)端創(chuàng)建新Socket(或用多線(xiàn)程)單Socket即可處理多客戶(hù)端(通過(guò)地址區(qū)分)

四、實(shí)踐建議

  1. 協(xié)議選擇:對(duì)可靠性要求高的場(chǎng)景(如文件傳輸、登錄認(rèn)證)用TCP;對(duì)實(shí)時(shí)性要求高的場(chǎng)景(如視頻通話(huà)、游戲)用UDP。
  2. 錯(cuò)誤處理:實(shí)際編程中需強(qiáng)化錯(cuò)誤處理(如連接超時(shí)、數(shù)據(jù)截?cái)嗟龋?/li>
  3. 性能優(yōu)化:TCP可通過(guò)調(diào)整緩沖區(qū)大小優(yōu)化性能;UDP需控制數(shù)據(jù)報(bào)大?。ū苊釯P分片)。
  4. 安全性:敏感場(chǎng)景需在Socket通信基礎(chǔ)上添加加密(如SSL/TLS)。

通過(guò)掌握兩種協(xié)議的Socket編程差異,可根據(jù)實(shí)際需求選擇合適的通信方式,構(gòu)建高效、可靠的網(wǎng)絡(luò)應(yīng)用。

到此這篇關(guān)于TCP與UDP協(xié)議的Socket編程的文章就介紹到這了,更多相關(guān)TCP與UDP協(xié)議的Socket編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Matlab中自帶的Java操作合集

    詳解Matlab中自帶的Java操作合集

    其實(shí)Matlab中也有一些自帶的Java操作,例如:獲取鼠標(biāo)在全屏位置、獲取當(dāng)前剪切板內(nèi)容、獲取鼠標(biāo)處像素顏色等,本文總結(jié)了七個(gè)這樣的操作,感興趣的可以了解一下
    2022-03-03
  • C++ OpenCV實(shí)戰(zhàn)之手勢(shì)識(shí)別

    C++ OpenCV實(shí)戰(zhàn)之手勢(shì)識(shí)別

    這篇文章主要介紹了如何利用C++?OpenCV實(shí)現(xiàn)手勢(shì)識(shí)別,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定幫助,感興趣的小伙伴可以了解一下
    2022-04-04
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)系列隊(duì)列篇

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)系列隊(duì)列篇

    本章我們將學(xué)習(xí) "隊(duì)列" ,首先介紹隊(duì)列的概念和結(jié)構(gòu),然后我們將著重講解棧的實(shí)現(xiàn)。我們從零開(kāi)始寫(xiě)隊(duì)列的接口,并從零開(kāi)始步步解讀。本章將繼續(xù)鞏固畫(huà)思路草圖的能力,只要思路草圖畫(huà)好了,就可以很輕松地將其轉(zhuǎn)換成代碼
    2022-02-02
  • C語(yǔ)言基礎(chǔ)文件操作方式超全詳解建議收藏

    C語(yǔ)言基礎(chǔ)文件操作方式超全詳解建議收藏

    這篇文章主要為大家介紹了關(guān)于C語(yǔ)言文件操作方式的詳細(xì)總結(jié),建議收藏隨用隨看,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • C語(yǔ)言遞歸實(shí)現(xiàn)掃雷游戲

    C語(yǔ)言遞歸實(shí)現(xiàn)掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言遞歸實(shí)現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 二叉樹(shù)先根(先序)遍歷的改進(jìn)

    二叉樹(shù)先根(先序)遍歷的改進(jìn)

    這篇文章主要介紹了二叉樹(shù)先根(先序)遍歷的改進(jìn),有需要的朋友可以參考一下
    2014-01-01
  • mfc文件操作CFile類(lèi)之創(chuàng)建文件的方法

    mfc文件操作CFile類(lèi)之創(chuàng)建文件的方法

    這篇文章主要介紹了mfc文件操作CFile類(lèi)之創(chuàng)建文件的方法,需要的朋友可以參考下
    2019-04-04
  • C++vector的insert函數(shù)用法小結(jié)

    C++vector的insert函數(shù)用法小結(jié)

    std::vector::insert是C++中用于在指定位置插入元素的函數(shù),支持插入單個(gè)元素、多個(gè)相同元素、一個(gè)范圍的元素或初始化列表中的元素,插入操作可能會(huì)使插入點(diǎn)之后的迭代器失效,并且時(shí)間復(fù)雜度為O(n),本文介紹C++vector的insert函數(shù)用法小結(jié),感興趣的朋友一起看看吧
    2025-03-03
  • C語(yǔ)言實(shí)現(xiàn)水波紋效果

    C語(yǔ)言實(shí)現(xiàn)水波紋效果

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)水波紋效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C++ 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)(前序/中序/后序遞歸、非遞歸遍歷)

    C++ 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)(前序/中序/后序遞歸、非遞歸遍歷)

    這篇文章主要介紹了C++ 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)(前序/中序/后序遞歸、非遞歸遍歷)的相關(guān)資料,這里提供實(shí)例代碼來(lái)幫助大家理解掌握二叉樹(shù),需要的朋友可以參考下
    2017-07-07

最新評(píng)論

本溪市| 阳山县| 台南市| 新乡县| 山西省| 富阳市| 平顺县| 平顺县| 富阳市| 盖州市| 莎车县| 远安县| 鲜城| 左权县| 察隅县| 师宗县| 怀宁县| 绍兴市| 商洛市| 黑山县| 泰兴市| 德昌县| 马关县| 普兰店市| 平度市| 阿尔山市| 文安县| 遵化市| 建昌县| 湘西| 九龙坡区| 女性| 兴义市| 吉木乃县| 英吉沙县| 山阴县| 塔河县| 上虞市| 四子王旗| 黎平县| 宿松县|