《TCP/IP网络编程》

最近看了下《TCP/IP网络编程》这本书,想自己实现一下TCP通信的客户端和服务器端
下面是源代码

Ser.c

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

#pragma comment(lib, "ws2_32.lib")

struct CustomMessage {
    char university[4]; //  "AHU\0"
    char major[32]; //  专业
    char data[256]; //  消息数据
};

int main() {
    // 初始化 Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        fprintf(stderr, "Failed to initialize Winsock\n");
        return 1;
    }

    // 创建套接字
    SOCKET server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket == INVALID_SOCKET) {
        fprintf(stderr, "Socket creation failed\n");
        WSACleanup();
        return 1;
    }

    // 绑定端口
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = INADDR_ANY;
    server_address.sin_port = htons(8888);

    if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == SOCKET_ERROR) {
        fprintf(stderr, "Bind failed\n");
        closesocket(server_socket);
        WSACleanup();
        return 1;
    }

    // 监听
    if (listen(server_socket, SOMAXCONN) == SOCKET_ERROR) {
        fprintf(stderr, "Listen failed\n");
        closesocket(server_socket);
        WSACleanup();
        return 1;
    }

    printf("Server listening on port 8888...\n");

    while (1) {
        // 接受连接
        SOCKET client_socket = accept(server_socket, NULL, NULL);
        if (client_socket == INVALID_SOCKET) {
            fprintf(stderr, "Accept failed\n");
            closesocket(server_socket);
            WSACleanup();
            return 1;
        }

        // 接收自定义消息
        struct CustomMessage received_message;
        int bytes_received = recv(client_socket, (char*)&received_message, sizeof(struct CustomMessage), 0);
        if (bytes_received > 0) {
            printf("Received Message:\n");
            printf("University: %s\n", received_message.university);
            printf("Major: %s\n", received_message.major);
            printf("Data: %s\n", received_message.data);
        }
        else if (bytes_received == 0) {
            printf("Client disconnected\n");
            closesocket(client_socket);
            continue;  // 继续等待下一个连接
        }
        else {
            fprintf(stderr, "Receive failed\n");
            closesocket(client_socket);
            continue;  // 继续等待下一个连接
        }

        // 关闭客户端套接字
        closesocket(client_socket);
    }

    // 关闭服务器套接字
    closesocket(server_socket);

    // 清理 Winsock
    WSACleanup();

    return 0;
}

Cli.c

#include <stdio.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include<tchar.h>

#pragma comment(lib, "ws2_32.lib")

struct CustomMessage {
    char university[4]; // "AHU\0"
    char major[32]; // 专业
    char data[256]; // 消息数据
};

int main() {
    // 初始化 Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        fprintf(stderr, "Failed to initialize Winsock\n");
        return 1;
    }

    // 创建套接字
    SOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (client_socket == INVALID_SOCKET) {
        fprintf(stderr, "Socket creation failed\n");
        WSACleanup();
        return 1;
    }

    // 连接服务器
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    if (InetPton(AF_INET, _T("127.0.0.1"), &(server_address.sin_addr)) != 1) {
        fprintf(stderr, "Invalid IP address\n");
        closesocket(client_socket);
        WSACleanup();
        return 1;
    }
    server_address.sin_port = htons(8888);

    if (connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == SOCKET_ERROR) {
        fprintf(stderr, "Connection failed\n");
        closesocket(client_socket);
        WSACleanup();
        return 1;
    }

    while (1) {
        // 获取用户输入的消息
        printf("请输入要发送的消息 (输入 exit 结束): ");
        struct CustomMessage message_to_send;
        fgets(message_to_send.data, sizeof(message_to_send.data), stdin);
        message_to_send.data[strcspn(message_to_send.data, "\n")] = '\0'; // 移除换行符
        strcpy_s(message_to_send.university, sizeof(message_to_send.university), "AHU");//以AHU开头
        strcpy_s(message_to_send.major, sizeof(message_to_send.major), "CS"); // 设置专业为"CS"
        // 发送自定义消息
        int bytes_sent = send(client_socket, (const char*)&message_to_send, sizeof(struct CustomMessage), 0);
        if (bytes_sent == SOCKET_ERROR) {
            fprintf(stderr, "Send failed\n");
            closesocket(client_socket);
            WSACleanup();
            return 1;
        }

        // 如果用户输入 "exit",结束循环
        if (strcmp(message_to_send.data, "exit") == 0) {
            break;
        }
    }

    // 关闭客户端套接字
    closesocket(client_socket);

    // 清理 Winsock
    WSACleanup();

    return 0;
}

运行

先运行Ser.c,再运行Cli.c
image

完工!

posted @ 2024-03-13 16:24  go__Ahead  阅读(3)  评论(0编辑  收藏  举报