Linux網絡編程

一、基礎概念

Linux網絡編程涉及到一些基礎概念,包括Socket、IP地址、端口等。Socket是Linux網絡編程的核心,它是應用程序與網絡協議之間的接口,可以進行網絡通信。IP地址是網絡中唯一標識一個主機的數值地址,通過它可以進行網絡通信。而端口是用於標識一個應用程序的地址,只有在同一IP地址下,不同端口的應用程序才能進行通信。

下面是基於Socket的簡單TCP服務器端代碼示例:

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

int main()
{
    // 創建socket
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);

    // 設置socket運行參數
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    // 綁定socket
    bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));

    // 監聽socket
    listen(server_socket, 5);

    // 等待客戶端連接
    int client_socket = accept(server_socket, NULL, NULL);

    // 向客戶端發送消息
    char message[] = "Hello, World!";
    send(client_socket, message, sizeof(message), 0);

    // 關閉socket
    close(client_socket);
    close(server_socket);

    return 0;
}

二、套接字編程

Linux網絡編程中,套接字編程是最常用的編程方式。套接字編程使用Socket接口,通過系統調用Bind、Listen、Accept、Connect、Recv、Send等方法實現網絡通信,包括TCP、UDP、Raw Socket等多種協議。

下面是基於Socket的簡單TCP客戶端代碼示例:

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

int main()
{
    // 創建socket
    int client_socket = socket(AF_INET, SOCK_STREAM, 0);

    // 設置socket運行參數
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    inet_pton(AF_INET, "127.0.0.1", &server_address.sin_addr);

    // 連接服務器
    connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address));

    // 接收服務器消息
    char message[100];
    recv(client_socket, message, 100, 0);

    // 輸出服務器消息
    printf("%s\n", message);

    // 關閉socket
    close(client_socket);

    return 0;
}

三、網絡通信協議

一個網絡應用系統中,各個層次之間通信需要遵循不同的協議,包括物理層協議、數據鏈路層協議、網絡層協議、傳輸層協議和應用層協議。Linux網絡編程涉及到的主要協議有TCP/IP協議、UDP協議、ICMP協議、ARP協議等。其中,TCP/IP協議是最常用的網絡通信協議,它實現了可靠的數據傳輸,可以確保數據的正確性。

下面是基於Socket的簡單UDP服務器端代碼示例:

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

int main()
{
    // 創建socket
    int server_socket = socket(AF_INET, SOCK_DGRAM, 0);

    // 設置socket運行參數
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9003);
    server_address.sin_addr.s_addr = INADDR_ANY;

    // 綁定socket
    bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));

    // 接收客戶端消息
    char message[100];
    struct sockaddr_in client_address;
    socklen_t client_length = sizeof(client_address);
    recvfrom(server_socket, message, 100, 0, (struct sockaddr*)&client_address, &client_length);

    // 輸出客戶端IP地址及消息內容
    printf("Message from [%s]: %s\n", inet_ntoa(client_address.sin_addr), message);

    // 關閉socket
    close(server_socket);

    return 0;
}

下面是基於Socket的簡單UDP客戶端代碼示例:

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

int main()
{
    // 創建socket
    int client_socket = socket(AF_INET, SOCK_DGRAM, 0);

    // 設置socket運行參數
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9003);
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1");

    // 發送消息到服務器
    char message[] = "Hello, server!";
    sendto(client_socket, message, sizeof(message), 0, (struct sockaddr*)&server_address, sizeof(server_address));

    // 關閉socket
    close(client_socket);

    return 0;
}

四、多線程網絡編程

多線程網絡編程是指在一個進程中,啟動多個線程來處理網絡請求。它可以提高程序並發處理能力,同時也需要注意線程間的同步、互斥等問題。

下面是基於Socket的簡單多線程TCP服務器端代碼示例:

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

void* handle_client(void* arg)
{
    // 接收客戶端消息
    char message[100];
    int client_socket = *((int*)arg);
    recv(client_socket, message, 100, 0);

    // 輸出客戶端消息
    printf("%s\n", message);

    // 向客戶端發送消息
    char reply[] = "I have received your message!";
    send(client_socket, reply, sizeof(reply), 0);

    // 關閉socket
    close(client_socket);

    return NULL;
}

int main()
{
    // 創建socket
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);

    // 設置socket運行參數
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9004);
    server_address.sin_addr.s_addr = INADDR_ANY;

    // 綁定socket
    bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));

    // 監聽socket
    listen(server_socket, 5);

    // 創建線程處理客戶端請求
    pthread_t thread_id;
    while(1)
    {
        int client_socket = accept(server_socket, NULL, NULL);
        pthread_create(&thread_id, NULL, handle_client, &client_socket);
    }

    // 關閉socket
    close(server_socket);

    return 0;
}

五、網絡安全編程

Linux網絡編程中,網絡安全編程是十分重要的內容。網絡安全編程主要包括SSL/TLS協議、數字簽名、加解密等技術,可以保證網絡通信的安全性。

下面是基於SSL/TLS協議的簡單TCP服務器端代碼示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

void init_openssl()
{
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();
}

void cleanup_openssl()
{
    ERR_free_strings();
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
}

SSL_CTX* create_context()
{
    const SSL_METHOD* method;
    SSL_CTX* ctx;

    method = TLSv1_2_server_method();

    ctx = SSL_CTX_new(method);
    if (!ctx)
    {
        perror("Unable to create SSL context");
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    return ctx;
}

void configure_context(SSL_CTX* ctx)
{
    SSL_CTX_set_ecdh_auto(ctx, 1);

    if (SSL_CTX_use_certificate_file(ctx, "cert.pem", SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    if (SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM) <= 0 )
    {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }
}

int main()
{
    // 初始化OpenSSL
    SSL_CTX* ctx;
    init_openssl();
    ctx = create_context();
    configure_context(ctx);

    // 創建socket
    int server_socket = socket(AF_INET, SOCK_STREAM, 0);

    // 設置socket運行參數
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9005);
    server_address.sin_addr.s_addr = INADDR_ANY;

    // 綁定socket
    bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address));

    // 監聽socket
    listen(server_socket, 5);

    // 接收客戶端連接並進行SSL握手
    while(1)
    {
        struct sockaddr_in client_address;
        unsigned int client_length = sizeof(client_address);
        int client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_length);

        SSL* ssl = SSL_new(ctx);
        SSL_set_fd(ssl, client_socket);

        if (SSL_accept(ssl) <= 0)
        {
            ERR_print_errors_fp(stderr);
        }
        else
        {
            // 向客戶端發送消息
            char message[] = "Hello, World!";
            SSL_write(ssl, message, sizeof(message));

            // 接收客戶端消息
            char buffer[100];
            SSL_read(ssl, buffer, 100);
            printf("Client message: %s\n", buffer);
        }

        // 關閉SSL連接
        SSL_shutdown(ssl);
        SSL_free(ssl);

        // 關閉socket
        close(client_socket);
    }

    // 關閉socket
    close(server_socket);

    // 清理OpenSSL
    cleanup_openssl();

    return 0;
}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/240271.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:21
下一篇 2024-12-12 12:21

相關推薦

  • 如何在Linux中添加用戶並修改配置文件

    本文將從多個方面詳細介紹在Linux系統下如何添加新用戶並修改配置文件 一、添加新用戶 在Linux系統下創建新用戶非常簡單,只需使用adduser命令即可。使用以下命令添加新用戶…

    編程 2025-04-27
  • 如何解決linux jar包 invalid or corrupt jarfile問題

    對於許多開發人員和系統管理員在Linux環境下使用Java開發過程中遇到的一個常見的問題是 invalid or corrupt jarfile(無效或損壞的jar文件)錯誤。當您…

    編程 2025-04-27
  • 在Linux上安裝JRE並配置環境變量

    本文將從以下幾個方面為您詳細闡述如何在Linux系統上,通過自己賬戶安裝JRE,並且配置環境變量。 一、安裝JRE 在進行安裝前,我們需要下載JRE的安裝包並解壓,可以從官方網站下…

    編程 2025-04-27
  • GTKAM:Linux下的照片管理器

    GTKAM是用於Linux操作系統的一款照片管理器,它支持多種相機及存儲設備,並提供了一系列強大的工具,讓用戶可以方便地瀏覽、管理、編輯和導出照片。本文將從多個方面對GTKAM進行…

    編程 2025-04-27
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁盤中。在執行sync之前,所有的文件系統更新將不會立即寫入磁盤,而是先緩存在內存…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25
  • 如何在Windows/Linux/MacOS下安裝Python

    如果你對Python安裝一無所知,本文將從多個方面對Python在Windows/Linux/MacOS下的安裝做出詳細闡述,為初學者提供幫助。 一、Windows下Python的…

    編程 2025-04-25
  • Linux網絡連接激活失敗原因及解決方法

    一、網卡驅動問題 1、缺少網卡驅動 若使用新的網卡,需要安裝對應網卡驅動,否則會導致網絡連接激活失敗。可通過以下命令查看當前系統中是否存在網卡驅動: lsmod | grep et…

    編程 2025-04-25
  • Linux Redis 重啟

    一、概述 Redis 是一款高性能的 NoSQL 數據庫,常用於各種應用場景的數據緩存、消息隊列、實時數據分析等等。在使用 Redis 過程中,如果出現了某些問題,有時候只需要重啟…

    編程 2025-04-25
  • Linux防火牆配置詳解

    一、iptables基本介紹 iptables是一個重要的Linux內核中網絡安全系統,通過設置iptables規則,可以對進入和離開Linux服務器的數據進行過濾。 iptabl…

    編程 2025-04-25

發表回復

登錄後才能評論