欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

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

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

1. 核心流程

服務(wù)器端流程:

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

客戶端流程:

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

2. TCP Socket編程示例

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

#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è)置套接字選項,允許端口復用
    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)聽連接請求(最大等待隊列長度為5)
    if (listen(server_fd, 5) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    
    printf("TCP Server listening on port %d...\n", PORT);

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

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

    // 向客戶端發(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;
}

客戶端代碼(C語言):

#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)二進制)
    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ù)器(三次握手在此過程完成)
    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(用戶數(shù)據(jù)報協(xié)議)是無連接的不可靠傳輸協(xié)議,其Socket編程無需建立連接,直接發(fā)送數(shù)據(jù)報,類似現(xiàn)實中的"寄明信片"場景。

1. 核心流程

服務(wù)器端流程:

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

客戶端流程:

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

2. UDP Socket編程示例

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

#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ù)報套接字)
    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. 接收客戶端數(shù)據(jù)報(阻塞等待,同時獲取客戶端地址)
    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);

    // 向客戶端發(fā)送響應(yīng)(需指定客戶端地址)
    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;
}

客戶端代碼(C語言):

#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ù)報(需指定服務(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編程的核心差異

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

四、實踐建議

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

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

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

相關(guān)文章

  • C++實現(xiàn)屏幕截圖(全屏截圖)

    C++實現(xiàn)屏幕截圖(全屏截圖)

    屏幕截圖已經(jīng)成為了所有IM即時通訊軟件的必備模塊,也是日常辦公中使用最頻繁的功能之一。今天我們從C++開發(fā)的角度,來看看屏幕截圖的主要功能點是如何實現(xiàn)的,感興趣的可以了解一下
    2021-11-11
  • C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能

    C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能

    這篇文章主要介紹了C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能,幫助大家提高程序運行速度,感興趣的朋友可以了解下
    2020-10-10
  • C語言數(shù)組詳細介紹

    C語言數(shù)組詳細介紹

    大家好,本篇文章主要講的是C語言數(shù)組詳細介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • C++ Primer 標準庫vector示例詳解

    C++ Primer 標準庫vector示例詳解

    該文章主要介紹了C++標準庫中的vector類型,包括其定義、初始化、成員函數(shù)以及常見操作,文章詳細解釋了如何使用vector來存儲和操作對象集合,并提供了代碼示例來說明vector的使用方法,感興趣的朋友一起看看吧
    2025-03-03
  • 基于OpenCv的運動物體檢測算法

    基于OpenCv的運動物體檢測算法

    這篇文章主要為大家詳細介紹了基于OpenCv的運動物體檢測算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Qt使用HTTP上傳json格式數(shù)據(jù)

    Qt使用HTTP上傳json格式數(shù)據(jù)

    這篇文章主要為大家詳細介紹了Qt如何使用HTTP上傳json格式數(shù)據(jù),文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2024-12-12
  • Qt視頻播放器的實現(xiàn)示例

    Qt視頻播放器的實現(xiàn)示例

    本文主要介紹了Qt視頻播放器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-08-08
  • C語言光標旋轉(zhuǎn)與倒計時功能實現(xiàn)示例詳解

    C語言光標旋轉(zhuǎn)與倒計時功能實現(xiàn)示例詳解

    這篇文章主要為大家介紹了C語言實現(xiàn)光標旋轉(zhuǎn)與倒計時功能的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2021-11-11
  • C語言每日練習之進制轉(zhuǎn)換

    C語言每日練習之進制轉(zhuǎn)換

    這篇文章主要介紹了C語言進制轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-11-11
  • C語言SQLite3事務(wù)和鎖的操作實例

    C語言SQLite3事務(wù)和鎖的操作實例

    這篇文章主要介紹了C語言SQLite3事務(wù)和鎖的操作,結(jié)合完整實例形式分析了C語言針對SQLite3數(shù)據(jù)庫的事務(wù)與鎖相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07

最新評論