基于windows的tcp服务器端/客户端

一个计算器的例子:

客户端连接到服务器端后以1字节整数形式传递待算数字个数;

客户端向服务器端传递的每个整数型数据占用4字节;

传递整数型数据后接着传递运算符,运算符占1个字节;

服务器端以4字节整数型向客户端传回计算结果。

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>

#define BUF_SIZE 1024
#define OP_NUM_SIZE 4 // 操作数的字节数

void ErrorHandling(char* message);
int calculate(int op_count, int num[], char op);

int main()
{
    WSADATA wsa_data;
    SOCKET server_sock, client_sock;
    SOCKADDR_IN server_addr, client_sock_addr;
    char op_info[BUF_SIZE];
    int result, op_count;
    int recv_cnt, recv_len;
    int client_sock_size;

    if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
        ErrorHandling("WSAStartup() error.");

    server_sock = socket(PF_INET, SOCK_STREAM, 0);
    if (server_sock == INVALID_SOCKET)
        ErrorHandling("socket() error.");

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(8000);

    if (bind(server_sock, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
        ErrorHandling("bind() error.");
    if (listen(server_sock, 5) == SOCKET_ERROR)
        ErrorHandling("listen() error.");

    client_sock_size = sizeof(client_sock_addr);
    for (int i = 0; i < 5; ++i)
    {
        op_count = 0;
        client_sock = accept(server_sock, (SOCKADDR*)&client_sock_addr, &client_sock_size);
        if (client_sock == INVALID_SOCKET)
            ErrorHandling("accept() error.");
        recv(client_sock, (char*)&op_count, 1, 0);
        printf("recv op_count: %d\n", op_count);
        recv_len = 0;
        while (op_count * OP_NUM_SIZE + 1 > recv_len)
        {
            recv_cnt = recv(client_sock, &op_info[recv_len], BUF_SIZE - 1, 0);
            recv_len += recv_cnt;
        }
        result = calculate(op_count, (int*)op_info, op_info[recv_len - 1]);
        printf("calculate result: %d\n", result);
        send(client_sock, (char*)&result, sizeof(result), 0);
        closesocket(client_sock);
    }
    closesocket(server_sock);
    WSACleanup();
    return 0;
}

void ErrorHandling(char* message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int calculate(int op_count, int num[], char op)
{
    int result = num[0];
    switch (op)
    {
    case '+':
        for (int i = 1; i < op_count; ++i) result += num[i];
        break;
    case '-':
        for (int i = 1; i < op_count; ++i) result -= num[i];
        break;
    case '*':
        for (int i = 1; i < op_count; ++i) result *= num[i];
        break;
    default:
        printf("???");
        break;
    }
    return result;
}

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>

#define BUF_SIZE 1024
#define RLT_SIZE 4 // 服务器端返回结果的字节数
#define OP_NUM_SIZE 4 // 操作数的字节数

void ErrorHandling(char* message);

int main()
{
    WSADATA wsa_data;
    SOCKET h_socket;
    SOCKADDR_IN server_addr;
    char op_msg[BUF_SIZE];
    int result, op_count;

    if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
        ErrorHandling("WSAStartup() error.");

    h_socket = socket(PF_INET, SOCK_STREAM, 0);
    if (h_socket == INVALID_SOCKET)
        ErrorHandling("socket() error.");

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(8000);

    if (connect(h_socket, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
        ErrorHandling("connect() error.");
    else
        puts("Connect......");

    fputs("Operand count: ", stdout);
    scanf("%d", &op_count);
    op_msg[0] = (char)op_count;
    for (int i = 0; i < op_count; ++i)
    {
        printf("Operand %d: ", i + 1);
        scanf("%d", (int*)&op_msg[i*OP_NUM_SIZE + 1]);
    }
    fgetc(stdin);
    fputs("Operator: ", stdout);
    scanf("%c", &op_msg[op_count * OP_NUM_SIZE + 1]);
    send(h_socket, op_msg, op_count * OP_NUM_SIZE + 2, 0);
    recv(h_socket, (char*)&result, RLT_SIZE, 0);

    printf("Operation result: %d\n", result);
    closesocket(h_socket);
    WSACleanup();
    return 0;
}

void ErrorHandling(char* message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

猜你喜欢

转载自www.cnblogs.com/ACGame/p/9906647.html