请求提供一个编程任务:基于指定文档,请给出客户端和服务端完整的代码实现,以满足文档中关于功能交互和通信的要求。包括所有必要的接口定义、连接设置、数据传输以及错误处理部分。请确保代码结构清晰,易于理解,并能成功实现文档所描述的功能。
时间: 2024-12-05 14:21:51 浏览: 11
为了完成《结构化任务一.docx》中的要求,以下是客户端和服务端的完整代码示例。这些代码实现了基本的Socket通信、设备入网认证和安全通信(使用AES对称加密)。
### 服务端代码 (server.c)
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <openssl/aes.h>
#define PORT 8080
#define BUFFER_SIZE 1024
#define MAX_CLIENTS 5
// 预存的设备ID和认证信息
typedef struct {
char device_id[20];
char auth_code[20];
} Device;
Device devices[] = {{"device1", "pass1"}, {"device2", "pass2"}};
int num_devices = sizeof(devices) / sizeof(Device);
void handle_client(SOCKET client_socket);
int authenticate(char *device_id, char *auth_code);
void aes_encrypt(const unsigned char *plaintext, int plaintext_len, const unsigned char *key, unsigned char *ciphertext);
void aes_decrypt(const unsigned char *ciphertext, int ciphertext_len, const unsigned char *key, unsigned char *plaintext);
int main() {
WSADATA wsa;
SOCKET server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// Initialize Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("Failed to initialize Winsock.\n");
return -1;
}
// Create a socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Socket creation failed.\n");
return -1;
}
// Bind the socket to an IP and port
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)) < 0) {
perror("Bind failed.");
return -1;
}
// Listen for incoming connections
if (listen(server_fd, MAX_CLIENTS) < 0) {
perror("Listen failed.");
return -1;
}
printf("Server is listening on port %d...\n", PORT);
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (int *)&addrlen)) < 0) {
perror("Accept failed.");
continue;
}
printf("New connection accepted.\n");
handle_client(new_socket);
closesocket(new_socket);
}
closesocket(server_fd);
WSACleanup();
return 0;
}
void handle_client(SOCKET client_socket) {
char buffer[BUFFER_SIZE] = {0};
char response[BUFFER_SIZE] = {0};
char key[AES_BLOCK_SIZE] = "thisisaverysecretkey"; // 对称加密密钥
unsigned char encrypted_data[BUFFER_SIZE] = {0};
unsigned char decrypted_data[BUFFER_SIZE] = {0};
// Receive device ID and auth code
recv(client_socket, buffer, BUFFER_SIZE, 0);
printf("Received: %s\n", buffer);
// Extract device ID and auth code
sscanf(buffer, "%[^:]:%s", buffer, buffer + strlen(buffer) + 1);
char *device_id = strtok(buffer, ":");
char *auth_code = strtok(NULL, ":");
// Authenticate the device
if (authenticate(device_id, auth_code)) {
strcpy(response, "Authentication successful.");
} else {
strcpy(response, "Authentication failed.");
send(client_socket, response, strlen(response), 0);
closesocket(client_socket);
return;
}
// Send welcome message
send(client_socket, response, strlen(response), 0);
// Secure communication loop
while (1) {
int n = recv(client_socket, encrypted_data, BUFFER_SIZE, 0);
if (n <= 0) break; // Connection closed or error
// Decrypt received data
aes_decrypt(encrypted_data, n, key, decrypted_data);
printf("Decrypted data: %s\n", decrypted_data);
// Echo back the decrypted data
aes_encrypt(decrypted_data, n, key, encrypted_data);
send(client_socket, encrypted_data, n, 0);
}
}
int authenticate(char *device_id, char *auth_code) {
for (int i = 0; i < num_devices; i++) {
if (strcmp(device_id, devices[i].device_id) == 0 && strcmp(auth_code, devices[i].auth_code) == 0) {
return 1; // Authentication successful
}
}
return 0; // Authentication failed
}
void aes_encrypt(const unsigned char *plaintext, int plaintext_len, const unsigned char *key, unsigned char *ciphertext) {
AES_KEY aes_key;
AES_set_encrypt_key(key, 128, &aes_key);
AES_encrypt(plaintext, ciphertext, &aes_key);
}
void aes_decrypt(const unsigned char *ciphertext, int ciphertext_len, const unsigned char *key, unsigned char *plaintext) {
AES_KEY aes_key;
AES_set_decrypt_key(key, 128, &aes_key);
AES_decrypt(ciphertext, plaintext, &aes_key);
}
```
### 客户端代码 (client.c)
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <openssl/aes.h>
#define SERVER_IP "127.0.0.1"
#define PORT 8080
#define BUFFER_SIZE 1024
void connect_to_server();
void send_auth_request();
void secure_communication_loop();
void aes_encrypt(const unsigned char *plaintext, int plaintext_len, const unsigned char *key, unsigned char *ciphertext);
void aes_decrypt(const unsigned char *ciphertext, int ciphertext_len, const unsigned char *key, unsigned char *plaintext);
SOCKET sock;
int main() {
WSADATA wsa;
// Initialize Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("Failed to initialize Winsock.\n");
return -1;
}
connect_to_server();
send_auth_request();
secure_communication_loop();
closesocket(sock);
WSACleanup();
return 0;
}
void connect_to_server() {
struct sockaddr_in server_address;
// Create a socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Socket creation failed.\n");
return;
}
// Set up the server address structure
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr);
// Connect to the server
if (connect(sock, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
perror("Connection failed.");
return;
}
printf("Connected to server.\n");
}
void send_auth_request() {
char buffer[BUFFER_SIZE] = {0};
char device_id[] = "device1";
char auth_code[] = "pass1";
char response[BUFFER_SIZE] = {0};
// Send authentication request
sprintf(buffer, "%s:%s", device_id, auth_code);
send(sock, buffer, strlen(buffer), 0);
// Receive authentication response
recv(sock, response, BUFFER_SIZE, 0);
printf("Server response: %s\n", response);
}
void secure_communication_loop() {
char buffer[BUFFER_SIZE] = {0};
char key[AES_BLOCK_SIZE] = "thisisaverysecretkey"; // 对称加密密钥
unsigned char encrypted_data[BUFFER_SIZE] = {0};
unsigned char decrypted_data[BUFFER_SIZE] = {0};
while (1) {
// Read user input
fgets(buffer, BUFFER_SIZE, stdin);
buffer[strcspn(buffer, "\n")] = 0;
// Encrypt the message
aes_encrypt((const unsigned char *)buffer, strlen(buffer), key, encrypted_data);
// Send encrypted message
send(sock, encrypted_data, strlen(buffer), 0);
// Receive encrypted response
int n = recv(sock, encrypted_data, BUFFER_SIZE, 0);
if (n <= 0) break; // Connection closed or error
// Decrypt the response
aes_decrypt(encrypted_data, n, key, decrypted_data);
printf("Server response: %s\n", decrypted_data);
}
}
void aes_encrypt(const unsigned char *plaintext, int plaintext_len, const unsigned char *key, unsigned char *ciphertext) {
AES_KEY aes_key;
AES_set_encrypt_key(key, 128, &aes_key);
AES_encrypt(plaintext, ciphertext, &aes_key);
}
void aes_decrypt(const unsigned char *ciphertext, int ciphertext_len, const unsigned char *key, unsigned char *plaintext) {
AES_KEY aes_key;
AES_set_decrypt_key(key, 128, &aes_key);
AES_decrypt(ciphertext, plaintext, &aes_key);
}
```
### 说明
1. **服务端** (`server.c`):
- 监听指定端口,接受客户端连接。
- 处理客户端的认证请求,验证设备ID和认证码。
- 如果认证成功,发送欢迎消息并进入安全通信循环。
- 在安全通信循环中,接收加密数据,解密后回显加密数据。
2. **客户端** (`client.c`):
- 连接到服务端。
- 发送认证请求,包括设备ID和认证码。
- 接收认证响应,如果成功,进入安全通信循环。
- 在安全通信循环中,读取用户输入,加密后发送给服务端,并接收服务端的加密响应,解密后显示。
### 编译和运行
- 使用 `Dev-C++` 或 `Code::Blocks` 编译和运行上述代码。
- 确保安装了 OpenSSL 库,并在编译时链接相应的库文件。
希望这些代码能满足您的需求!如果有任何问题或需要进一步的帮助,请随时告知。
阅读全文