我正在学习unix套接字,我决定为本地通信编写一个简单的客户端/服务器程序。 它的工作原理如下:服务器创建一个套接字并开始监听,直到客户端连接,接收消息并简单地将其发送回客户端;另一方面,客户端连接到套接字,发送字符串消息,接收服务器响应并终止。
我成功实施了这样的程序。对于测试目的(我知道它没有意义,它只是一个测试),我想在消息的底部添加消息本身的哈希值。我使用了SHA256函数的OpenSSL实现,修改了如下行为:
现在,问题是我使用完全相同的函数来计算和验证散列,但是在服务器端我得到了一个哈希不匹配,而在客户端,一切都按预期工作。
我确定我做错了什么。
服务器输出:
Socket created
Bind done
Waiting for incoming connections...
Connection accepted
Message received
Message: hello
Hash not corresponding
Message sent
客户端输出:
Socket created
Connected
Enter message to send: hello
Message sent
Message received
Hashes match
Server reply: Hash mismatch
这是服务器代码:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/sha.h>
int simpleSHA256(void *input, unsigned long length, unsigned char *md) {
SHA256_CTX context;
if(!SHA256_Init(&context))
return 0;
if(!SHA256_Update(&context, (unsigned char*)input, length))
return 0;
if(!SHA256_Final(md, &context))
return 0;
return 1;
}
int main(int argc, char *argv[]) {
int socket_desc, client_sock, c;
struct sockaddr_in server, client;
char client_message[1000], client_plain_message[1000], server_message[1000], *received_client_message_hash;
// Create socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
printf("Could not create socket\n");
return 1;
}
printf("Socket created\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
// Bind
if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("Bind failed. Error");
close(socket_desc); close(client_sock); return 1;
}
printf("Bind done\n");
// Start listening
listen(socket_desc, 3);
printf("Waiting for incoming connections...\n");
c = sizeof(struct sockaddr_in);
// Accept connection
if ((client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) < 0) {
perror("Accept failed");
close(socket_desc); close(client_sock); return 1;
}
printf("Connection accepted\n");
// Receive message from client
if (recv(client_sock, client_message, 1000, 0) < 0 ) {
perror("Receive failed");
close(socket_desc); close(client_sock); return 1;
}
printf("Message received\n");
strcpy(client_plain_message, client_message);
strtok_r(client_plain_message, "|", &received_client_message_hash);
// Verify hash
unsigned char computed_client_message_hash[SHA256_DIGEST_LENGTH];
if(!simpleSHA256(client_plain_message, strlen(client_plain_message), computed_client_message_hash)) {
printf("Error computing hash\n");
close(socket_desc); close(client_sock); return 1;
}
printf("Message: %s\n", client_plain_message);
if (!strcmp(computed_client_message_hash, received_client_message_hash)) {
printf("Hash not corresponding\n");
strcpy(server_message, "Hash mismatch");
} else {
printf("Hashes match\n");
strcpy(server_message, client_plain_message);
strcat(server_message, "_added_text_");
}
// Compute new hash
unsigned char message_hash[SHA256_DIGEST_LENGTH];
if(!simpleSHA256(client_plain_message, strlen(client_plain_message), message_hash)) {
printf("Error computing hash\n");
close(socket_desc); close(client_sock); return 1;
}
// Concatenate new hash with response
strcat(server_message, "|");
strcat(server_message, message_hash);
// Ansers to client
if (write(client_sock, server_message, strlen(server_message)) < 0) {
perror("Write failed");
close(socket_desc); close(client_sock); return 1;
}
printf("Message sent\n");
fflush(stdout);
return 0;
}
这是客户端代码:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/sha.h>
int simpleSHA256(void *input, unsigned long length, unsigned char *md) {
SHA256_CTX context;
if(!SHA256_Init(&context))
return 0;
if(!SHA256_Update(&context, (unsigned char*)input, length))
return 0;
if(!SHA256_Final(md, &context))
return 0;
return 1;
}
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in server;
char client_message[1000], server_reply[1000], server_message[1000], *received_server_message_hash;
// Create socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("Could not create socket\n");
close(sock); return 1;
}
printf("Socket created\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1"); // destination ip
server.sin_port = htons(8888); // destination port
// Connect to server
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("Connect failed. Error\n");
return 1;
}
printf("Connected\n");
printf("Enter message to send: ");
scanf("%s", client_message);
// Compute hash
unsigned char client_message_hash[SHA256_DIGEST_LENGTH];
if(!SHA256(client_message, strlen(client_message), client_message_hash)) {
printf("Error computing hash\n");
close(sock); return 1;
}
// Concatenate hash with message
strcat(client_message, "|");
strcat(client_message, client_message_hash);
// Send message
if (write(sock, client_message, strlen(client_message)) < 0) {
printf("Write failed\n");
close(sock); return 1;
}
printf("Message sent\n");
// Receive response
if (recv(sock, server_reply, 1000, 0) < 0) {
printf("Receive failed\n");
close(sock); return 1;
}
printf("Message received\n");
strcpy(server_message, server_reply);
strtok_r(server_message, "|", &received_server_message_hash);
// Verify hash
unsigned char computed_server_message_hash[SHA256_DIGEST_LENGTH];
if(!simpleSHA256(server_message, strlen(server_message), computed_server_message_hash)) {
printf("Error computing hash\n");
close(sock); return 1;
}
// Check if hashes match
if (!strcmp(computed_server_message_hash, received_server_message_hash)) {
printf("Hash not corresponding\n");
close(sock); return 1;
}
printf("Hashes match\n");
printf("Server reply: %s\n", server_message);
// Close connection
close(sock);
return 0;
}
答案 0 :(得分:2)
你是
recv()
检查你的假设。
答案 1 :(得分:-1)
我通过将strlen()
替换为常量值来解决我的问题,正如alk所指出的那样。
注意:下面的代码只是一个测试,它并不意味着没有bug或完全可以用于任何目的。我将其发布为仅限于我遇到的问题的解决方案。
更新了客户端:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/sha.h>
#define MAX_LENGTH 10000
int simpleSHA256(void *input, unsigned long length, unsigned char *md) {
SHA256_CTX context;
if(!SHA256_Init(&context))
return 0;
if(!SHA256_Update(&context, (unsigned char*)input, length))
return 0;
if(!SHA256_Final(md, &context))
return 0;
return 1;
}
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in server;
char client_message[MAX_LENGTH], server_reply[MAX_LENGTH], server_message[MAX_LENGTH], *received_server_message_hash;
// Create socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("Could not create socket\n");
close(sock); return 1;
}
printf("Socket created\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1"); // destination ip
server.sin_port = htons(8888); // destination port
// Connect to server
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("Connect failed. Error\n");
return 1;
}
printf("Connected\n");
printf("Enter message to send: ");
scanf("%s", client_message);
// Compute hash
unsigned char client_message_hash[SHA256_DIGEST_LENGTH];
if(!SHA256(client_message, MAX_LENGTH, client_message_hash)) {
printf("Error computing hash\n");
close(sock); return 1;
}
// Concatenate hash with message
strcat(client_message, "|");
strcat(client_message, client_message_hash);
// Send message
if (write(sock, client_message, MAX_LENGTH) <= 0) {
printf("Write failed\n");
close(sock); return 1;
}
printf("Message sent\n");
// Receive response
if (recv(sock, server_reply, MAX_LENGTH, 0) <= 0) {
perror("Receive failed");
close(sock); return 1;
}
printf("Message received\n");
strcpy(server_message, server_reply);
strtok_r(server_message, "|", &received_server_message_hash);
// Verify hash
unsigned char computed_server_message_hash[SHA256_DIGEST_LENGTH];
if(!simpleSHA256(server_message, MAX_LENGTH, computed_server_message_hash)) {
printf("Error computing hash\n");
close(sock); return 1;
}
// Check if hashes match
if (!strcmp(computed_server_message_hash, received_server_message_hash)) {
printf("Hash not corresponding\n");
close(sock); return 1;
}
printf("Hashes match\n");
printf("Server reply: %s\n", server_message);
// Close connection
fflush(stdout);
close(sock);
return 0;
}
更新了服务器:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/sha.h>
#define MAX_LENGTH 10000
int simpleSHA256(void *input, unsigned long length, unsigned char *md) {
SHA256_CTX context;
if(!SHA256_Init(&context))
return 0;
if(!SHA256_Update(&context, (unsigned char*)input, length))
return 0;
if(!SHA256_Final(md, &context))
return 0;
return 1;
}
int main(int argc, char *argv[]) {
int socket_desc, client_sock, c;
struct sockaddr_in server, client;
char client_message[MAX_LENGTH], client_plain_message[MAX_LENGTH], server_message[MAX_LENGTH], *received_client_message_hash;
// Create socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
printf("Could not create socket\n");
return 1;
}
printf("Socket created\n");
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; // accetto da qualsiasi indirizzo
server.sin_port = htons(8888); // porta di ascolto
// Bind
if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
perror("Bind failed. Error");
close(socket_desc); close(client_sock); return 1;
}
printf("Bind done\n");
// Start listening
listen(socket_desc, 3);
printf("Waiting for incoming connections...\n");
c = sizeof(struct sockaddr_in);
// Accept connection
if ((client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) < 0) {
perror("Accept failed");
close(socket_desc); close(client_sock); return 1;
}
printf("Connection accepted\n");
// Receive message from client
if (recv(client_sock, client_message, MAX_LENGTH, 0) <= 0 ) {
perror("Receive failed");
close(socket_desc); close(client_sock); return 1;
}
printf("Message received\n");
strcpy(client_plain_message, client_message);
strtok_r(client_plain_message, "|", &received_client_message_hash);
printf("%i\n", strlen(client_plain_message));
// Verify hash
unsigned char computed_client_message_hash[SHA256_DIGEST_LENGTH];
if(!simpleSHA256(client_plain_message, MAX_LENGTH, computed_client_message_hash)) {
printf("Error computing hash\n");
close(socket_desc); close(client_sock); return 1;
}
printf("Message: %s\n", client_plain_message);
if (!strcmp(computed_client_message_hash, received_client_message_hash)) {
printf("Hash not corresponding\n");
strcpy(server_message, "Hash mismatch");
} else {
printf("Hashes match\n");
strcpy(server_message, client_plain_message);
strcat(server_message, "_added_text_");
}
// Compute new hash
unsigned char message_hash[SHA256_DIGEST_LENGTH];
if(!simpleSHA256(client_plain_message, MAX_LENGTH, message_hash)) {
printf("Error computing hash\n");
close(socket_desc); close(client_sock); return 1;
}
// Concatenate new hash with response
strcat(server_message, "|");
strcat(server_message, message_hash);
// Ansers to client
if (write(client_sock, server_message, MAX_LENGTH) <= 0) {
perror("Write failed");
close(socket_desc); close(client_sock); return 1;
}
printf("Message sent\n");
fflush(stdout);
close(socket_desc);
close(client_sock);
return 0;
}