C语言完成Socket通信

一.服务端实现

cs 复制代码
//
// Created by wyd on 2025/11/1.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <unistd.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    WSADATA wsa_data;
    int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
    if (result != 0) {
        printf("WSAStartup failed: %d", result);
        return 1;
    }

    // 1. 创建Socket(TCP,IPv4)
    SOCKET server_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server_fd == INVALID_SOCKET) {
        printf("socket failed: %d", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // 2. 绑定地址
    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡
    address.sin_port = htons(PORT); // 端口转网络字节序

    if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) == SOCKET_ERROR) {
        printf("bind failed: %d", WSAGetLastError());
        closesocket(server_fd);
        WSACleanup();
        return 1;
    }

    // 3. 监听连接
    if (listen(server_fd, 5) == SOCKET_ERROR) {
        printf("listen failed: %d", WSAGetLastError());
        closesocket(server_fd);
        WSACleanup();
        return 1;
    }

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

    // 4. 接受客户端连接
    struct sockaddr_in client_addr;
    int client_addr_len = sizeof(client_addr);

    SOCKET new_socket = accept(server_fd, (struct sockaddr*)&client_addr, &client_addr_len);
    if (new_socket == INVALID_SOCKET) {
        printf("accept failed: %d", WSAGetLastError());
        closesocket(server_fd);
        WSACleanup();
        return 1;
    }

    printf("Client connected.\n");


    // 5. 与客户端通信
    char buffer[BUFFER_SIZE];
    while (1) {
        // 接收数据
        int bytes_received = recv(new_socket, buffer, BUFFER_SIZE - 1, 0);
        if (bytes_received > 0) {
            buffer[bytes_received] = '\0'; // 确保字符串以 NULL 结尾
            printf("Received: %s\n", buffer);

            // 发送响应
            const char* response = "Hello from server!";
            send(new_socket, response, strlen(response), 0);
        } else if (bytes_received == 0) {
            printf("Client disconnected.\n");
            break;
        } else {
            printf("recv failed: %d\n", WSAGetLastError());
            break;
        }
    }

    // 6. 清理资源
    closesocket(new_socket);
    closesocket(server_fd);
    WSACleanup();
    return 0;
}

二.客户端实现

cs 复制代码
//
// Created by wyd on 2025/11/1.
//

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <string.h>

#define PORT 8080
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024

int main() {

    // 初始化
    WSADATA wsa_data;

    int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);

    // 初始化失败,初始化失败则退出程序
    if (result != 0)
    {
        printf("WSAStartup failed: %d", result);
        return 1;
    }

    // 1. 创建Socket
    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET)
    {
        printf("socket failed: %d", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // 2. 配置服务端地址
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // 使用 inet_addr 转换 IP 地址


    // 3. 连接服务端
    if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR)
    {
        printf("connect failed: %d", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    printf("Connected to server: %s:%d", SERVER_IP, PORT);

    // 4. 与服务器通信
    char buffer[BUFFER_SIZE];
    while (1) {
        // 输入消息
        printf("Enter message: ");
        fgets(buffer, BUFFER_SIZE, stdin);
        buffer[strcspn(buffer, "\n")] = '\0'; // 去掉换行符

        // 发送消息
        send(sock, buffer, strlen(buffer), 0);

        // 接收响应
        int bytes_received = recv(sock, buffer, BUFFER_SIZE - 1, 0);
        if (bytes_received > 0) {
            buffer[bytes_received] = '\0';
            printf("Server response: %s\n", buffer);
        } else if (bytes_received == 0) {
            printf("Server disconnected.\n");
            break;
        } else {
            printf("recv failed: %d\n", WSAGetLastError());
            break;
        }
    }


    // 5. 清理资源
    closesocket(sock);
    WSACleanup();

    return 0;
}

三.编译代码

GCC参数说明:
  • gcc:调用 GCC 编译器。
  • xxx.c:要编译的源文件。
  • -o xxx.exe:指定生成的目标文件名(可执行文件)。
  • -lws2_32:链接 Winsock 库(ws2_32.lib),这是 Windows 网络编程所必需的。

gcc server.c -o server.exe -lws2_32

gcc client.c -o client.exe -lws2_32

三.监听读取文件的案例

客户端Code
cs 复制代码
//
// Created by wyd on 2025/11/1.
//

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <string.h>

#define PORT 8080
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 4096

int main() {

    // 初始化
    WSADATA wsa_data;

    int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);

    // 初始化失败,初始化失败则退出程序
    if (result != 0)
    {
        printf("WSAStartup failed: %d", result);
        return 1;
    }

    // 1. 创建Socket
    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET)
    {
        printf("socket failed: %d", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // 2. 配置服务端地址
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // 使用 inet_addr 转换 IP 地址


    // 3. 连接服务端
    if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR)
    {
        printf("connect failed: %d", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    printf("Connected to server: %s:%d", SERVER_IP, PORT);

    FILE* fp = fopen("file_to_send.txt", "rb");
    if (!fp) {
        perror("Failed to open file");
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    // 4. 与服务器通信
    char buffer[BUFFER_SIZE];

    int bytes_read;
    while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, fp)) > 0) {
        send(sock, buffer, bytes_read, 0);
    }

    fclose(fp);

    // 5. 清理资源
    closesocket(sock);
    WSACleanup();

    return 0;
}
服务端Code
cs 复制代码
//
// Created by wyd on 2025/11/1.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <unistd.h>

#define PORT 8080
#define BUFFER_SIZE 4096

int main() {
    WSADATA wsa_data;
    int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
    if (result != 0) {
        printf("WSAStartup failed: %d", result);
        return 1;
    }

    // 1. 创建Socket(TCP,IPv4)
    SOCKET server_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server_fd == INVALID_SOCKET) {
        printf("socket failed: %d", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // 2. 绑定地址
    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡
    address.sin_port = htons(PORT); // 端口转网络字节序

    if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) == SOCKET_ERROR) {
        printf("bind failed: %d", WSAGetLastError());
        closesocket(server_fd);
        WSACleanup();
        return 1;
    }

    // 3. 监听连接
    if (listen(server_fd, 5) == SOCKET_ERROR) {
        printf("listen failed: %d", WSAGetLastError());
        closesocket(server_fd);
        WSACleanup();
        return 1;
    }

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

    // 4. 接受客户端连接
    struct sockaddr_in client_addr;
    int client_addr_len = sizeof(client_addr);

    SOCKET new_socket = accept(server_fd, (struct sockaddr*)&client_addr, &client_addr_len);
    if (new_socket == INVALID_SOCKET) {
        printf("accept failed: %d", WSAGetLastError());
        closesocket(server_fd);
        WSACleanup();
        return 1;
    }

    printf("Client connected.\n");


    // 5. 与客户端通信
    char buffer[BUFFER_SIZE];

    FILE* fp = fopen("received_file.txt","wb");
    if (!fp)
    {
        perror("Failed to open file");
        closesocket(new_socket);
        WSACleanup();
        return 1;
    }

    while (1) {
        // 接收数据
        int bytes_received = recv(new_socket, buffer, BUFFER_SIZE - 1, 0);
        if (bytes_received > 0) {
            buffer[bytes_received] = '\0'; // 确保字符串以 NULL 结尾

            fwrite(buffer, 1, bytes_received, fp);

            printf("Received: %s\n", buffer);

            // 发送响应
            const char* response = "Hello from server!";
            send(new_socket, response, strlen(response), 0);
        } else if (bytes_received == 0) {
            printf("Client disconnected.\n");
            break;
        } else {
            printf("recv failed: %d\n", WSAGetLastError());
            break;
        }
    }

    fclose(fp);

    // 6. 清理资源
    closesocket(new_socket);
    closesocket(server_fd);
    WSACleanup();
    return 0;
}

读取file_to_send.txt文件中的内容,则服务端也会输入内容copy到received_file.txt 完成监听工作

相关推荐
雨落在了我的手上41 分钟前
C语言入门(二十二):字符函数和字符串函数(2)
c语言
上海云盾安全满满3 小时前
高防 IP 是如何帮助数藏行业防刷
网络·网络协议·tcp/ip
qq_401700414 小时前
嵌入式用Unix时间的优势及其C语言转换
服务器·c语言·unix
多多*8 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven
p***43488 小时前
Rust网络编程模型
开发语言·网络·rust
NewCarRen8 小时前
汽车网络安全管理系统的需求分析及潜在框架设计
网络·汽车网络安全
捷米研发三部8 小时前
CC-Link转Modbus TCP协议转换网关实现三菱 PLC与传感器通讯在快递分拣中心的应用案例
网络·网络协议
嵌入式-小王8 小时前
每天掌握一个网络协议----ARP协议
网络·网络协议·arp
智者知已应修善业10 小时前
【51单片机普通延时奇偶灯切换】2023-4-4
c语言·经验分享·笔记·嵌入式硬件·51单片机
晚风(●•σ )10 小时前
C++语言程序设计——11 C语言风格输入/输出函数
c语言·开发语言·c++