首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

從零打造下載器:Socket 編程實戰入門

     編輯:關於C語言

什麼是下載器?

下載器本質上是一種網絡客戶端工具,其核心任務是從網絡服務器接收用戶所需的數據。整個下載流程遵循經典的客戶端-服務器模型:客戶端發起連接、發送資源請求,服務器響應並傳輸數據,客戶端接收並保存,一次簡單的下載即告完成。

Socket 編程:網絡應用的基石

所有網絡應用程序都建立在 Socket 編程之上。下載器的開發自然也從最基礎的 Socket 客戶端與服務端模型開始。以下以 Windows 平台、VC6.0 環境為例,展示最基礎的雙向通信代碼。

服務端代碼

#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32.lib")

void main() {
    WSADATA wsd;
    SOCKET server;
    SOCKADDR_IN addrSrv;
    char sendBuf[100], recvBuf[100];
    SOCKADDR_IN addrClient;
    SOCKET client;
    int len;

    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
        printf("WSAStartup failed!\n");
        return;
    }

    server = socket(AF_INET, SOCK_STREAM, 0);
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);

    bind(server, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
    listen(server, 5);

    len = sizeof(SOCKADDR);
    while (1) {
        client = accept(server, (SOCKADDR*)&addrClient, &len);
        sprintf(sendBuf, "Welcome %s", inet_ntoa(addrClient.sin_addr));
        send(client, sendBuf, strlen(sendBuf) + 1, 0);
        recv(client, recvBuf, 100, 0);
        printf("%s\n", recvBuf);
        closesocket(client);
    }
    closesocket(server);
    WSACleanup();
}

客戶端代碼

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32.lib")

void main() {
    WSADATA wsd;
    SOCKET sockClient;
    SOCKADDR_IN addrSrv;
    char recvBuf[100];

    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
        printf("WSAStartup failed!\n");
        return;
    }

    sockClient = socket(AF_INET, SOCK_STREAM, 0);
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);

    connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
    recv(sockClient, recvBuf, 100, 0);
    printf("%s\n", recvBuf);
    send(sockClient, "hello world", strlen("hello world") + 1, 0);

    closesocket(sockClient);
    WSACleanup();
}

從通信到文件傳輸:關鍵修改

理解了基本的 send/recv 流程後,只需稍作修改即可實現簡單的文件傳輸功能:

  • 客戶端:將發送內容改為請求的文件名 send(sockClient, filename, strlen(filename)+1, 0);
  • 服務端:接收文件名,打開文件並分塊發送:
    recv(client, filename, 100, 0);
    if ((fp = fopen(filename, "rb")) == NULL) { closesocket(client); return; }
    while ((n = fread(sendBuf, 1, 100, fp)) > 0) {
        send(client, sendBuf, n, 0);
    }
    
  • 客戶端接收:創建文件並循環寫入數據:
    
    if ((fp = fopen(filename, "wb")) == NULL) return;
    while ((ret = recv(sockClient, recvBuf, 100, 0)) > 0) {
        fwrite(recvBuf, 1, ret, fp);
    }
    

這樣,一個基於 Windows Socket 的簡易文件下載器雛形就完成了。這個例子清晰地展示了網絡編程的核心邏輯:連接、請求、傳輸、接收、斷開。

本文出自 “天天C” 博客,原文地址:https://kenshinf.blog.51cto.com/1088256/281910

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved