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 完成监听工作

相关推荐
im_AMBER2 小时前
Leetcode 46
c语言·c++·笔记·学习·算法·leetcode
light_forest4 小时前
tcp_connect_v4接口
java·网络·tcp/ip
时间醉酒4 小时前
数据结构:双向链表-从原理到实战完整指南
c语言·数据结构·算法
奔跑吧邓邓子5 小时前
【C语言实战(75)】C语言内存探秘:泄漏检测与分析实战
linux·c语言·windows·内存·开发实战·泄露检测
Nebula_g5 小时前
C语言应用实例:斐波那契数列与其其他应用
c语言·开发语言·后端·学习·算法
Matana1115 小时前
Vmware中主机ip a没有ip地址
服务器·网络·tcp/ip
千弥霜6 小时前
codeforces1914 C~F
c语言·算法
white-persist6 小时前
汇编代码详细解释:汇编语言如何转化为对应的C语言,怎么转化为对应的C代码?
java·c语言·前端·网络·汇编·安全·网络安全
2501_938810116 小时前
共享IP的定义
服务器·网络·tcp/ip