一个计算器的例子:
客户端连接到服务器端后以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); }