我正在尝试创建一个客户端 - 服务器脚本,就像我过去做过的许多其他脚本一样 但在这一个我有一个问题。如果我发布它给我的代码和输出会更好 代码:
#include <mysql.h> //not important now
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
//constant definition
#define SERVER_PORT 2121
#define LINESIZE 21
//global var definition
char victim_ip[LINESIZE], file_write[LINESIZE], hacker_ip[LINESIZE];
//function
void leggi (int); //not use now for debugging purpose
//void scriviDB (); //not important now
main () {
int sock, client_len, fd;
struct sockaddr_in server, client;
// transport end point
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("system call socket fail");
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("10.10.10.1");
server.sin_port = htons(SERVER_PORT);
// binding address at transport end point
if (bind(sock, (struct sockaddr *)&server, sizeof server) == -1) {
perror("system call bind fail");
exit(1);
}
//fprintf(stderr, "Server open: listening.\n");
listen(sock, 5);
/* managae client connection */
while (1) {
client_len = sizeof(client);
if ((fd = accept(sock, (struct sockaddr *)&client, &client_len)) < 0)
{ perror("accepting connection"); exit(1); }
strcpy(hacker_ip, inet_ntoa(client.sin_addr));
printf("1 %s\n", hacker_ip); //debugging purpose
//leggi(fd);
//////////////////////////
//receive client
recv(fd, victim_ip, LINESIZE, 0);
victim_ip[sizeof(victim_ip)] = '\0';
printf("2 %s\n", hacker_ip); //debugging purpose
recv(fd, file_write, LINESIZE, 0);
file_write[sizeof(file_write)] = '\0';
printf("3 %s\n", hacker_ip); //debugging purpose
printf("%s@%s for %s\n", file_write, victim_ip, hacker_ip);
//send to client
send(fd, hacker_ip, 40, 0); //now is hacker_ip for debug
/////////////////////////
close(fd);
}//end while
exit(0);
} //end main
客户端发送字符串:./ send -i 10.10.10.4 -f filename.ext
所以脚本在服务器上发送-i(IP)和-f(FILE)
这是我的输出服务器端:
1 10.10.10.6
2 10.10.10.6
3
如您所见,printf(3)和printf(ip,file,ip)失败 我不知道有人在哪里以及在哪里覆盖我的hacker_ip字符串 谢谢你的帮助! :)
答案 0 :(得分:3)
TCP提供流,而不是数据包。因此,您无法保证您发送的数据 1 send()调用需要1次recv()调用才能接收。可能需要几次recv()调用来接收send()调用发送的内容,或者可能需要1次recv()调用来接收发送的几个send()调用 - 不知怎的,你必须处理它。
特别是,你应该检查recv()的返回值,知道你收到了多少字节,这可能是一个开始,所以你至少不会在你的字符串中打印垃圾。
ssize_t bytes = recv(fd, victim_ip, LINESIZE, 0);
if(bytes == 0) {
//remote closed the connection, handle it
} else if (bytes < 0) {
//handle error
} else {
victim_ip[bytes] = '\0';
printf("%s\n", victim_ip);
}
答案 1 :(得分:1)
您应该纠正以下行:
victim_ip[sizeof(victim_ip)] = '\0';
和
file_write[sizeof(file_write)] = '\0';
这是覆盖hacker_ip字符串的那个。
在数组(sizeof(file_write) == LINE_SIZE)
结束后写入零。如果你想写一个看门狗零,你应该将数组的维度设置为另一个像file_write[LINE_SIZE+1]
这样的字符。
除此之外,它应该有效。对于像这里这样非常小的数据块(21个字节),数据包不太可能被分割(标准以太网帧大约为1400字节)。但是如果你做了几次发送,他们肯定会在同一个数据包中合并。
查看发件人代码会很有趣。你每次都发送一个完整的缓冲区吗? (应该看看你的recv())。