我正在尝试通过套接字注入远程代码,但是由于某种原因,当编写命令cd
或任何其他命令时,这反过来又通过客户端给了我一个答案,答案不会是输出到屏幕上。
我尝试了多种输出到屏幕的方法,但是它们都不起作用。
输出以下内容的服务器部分:
void *ReadAndWriteSocket(void *entrypoint) {
char message[256];
char buffer[256];
while (1) {
if((sockStructure.n = recv(sockStructure.newsockfd, buffer, strlen(buffer), 0)) > 0) {
for(int i = 0; i < strlen(buffer) - 1; i++) {
printf("%s", buffer[i]);
}
}
}
scanf("%s", &message);
send(sockStructure.newsockfd, message, strlen(message), 0);
}
客户代码:
require 'socket'
require 'open3'
def createClient(hostname, port)
s = TCPSocket.new hostname, port
while line = s.gets
if line == "exit"
s.close
elsif line[0..1] == "cd"
output = Dir.chdir(Dir.pwd + "/" + line[2..line.size].delete(" \t\n\r\0"))
s.puts(Dir.pwd)
end
stdin, stdout, stderr, wait_thr = Open3.popen3(line)
s.puts("#{stdout.read}")
end
end
createClient("127.0.0.1", 8082);
答案 0 :(得分:1)
即使您收到的数据量很小,也将阻塞scanf
,而不是尝试接收更多数据。您可能需要同时支持双向移动数据(等待在scanf
中输入数据和recv
中的数据),或者在更改方向时需要更加聪明。
请考虑以下情形:
ReadAndWriteSocket
。recv
的调用仅获得“ H”,即消息的第一个字节。printf
,但由于标准输出是行缓冲的,因此没有输出任何内容。scanf
并一直等待,但是什么也没发生,因为用户在看到收到的消息之前无意输入任何内容。recv
,这太糟糕了,因为接收到的其余消息正在接收缓冲区中等待,但是您陷于scanf
中。当您具有在两个方向上移动数据的代码时,必须绝对确保当要等待的数据向另一个方向发送时,您绝不会阻止等待一个方向的接收数据。您的代码没有什么可以防止这种情况。
更新:新代码存在问题:
void *ReadAndWriteSocket(void *entrypoint) {
char message[256];
char buffer[256];
while (1) {
if((sockStructure.n = recv(sockStructure.newsockfd, buffer, strlen(buffer), 0)) > 0) {
这是怎么回事?您只能将字符串传递给strlen
。但是buffer
此处不包含字符串(在第一次通过时未初始化,而在后续通过时包含无关的长度)。因此,您要将长度的荒谬值传递给recv
。
for(int i = 0; i < strlen(buffer) - 1; i++) {
printf("%s", buffer[i]);
这里有两个问题:首先,buffer[i]
不是字符串,而%s
格式说明符是字符串。其次,标准输出是行缓冲的,因此除非缓冲区碰巧包含一行,否则它不会显示。
}
}
}
scanf("%s", &message);
您为什么要在这里等待用户输入?如果您只收到一小部分消息,甚至没有收到整条消息,因此还没有输出任何内容怎么办?您怎么知道下一步需要做的是接收用户的输入,而不接收其余的消息?
send(sockStructure.newsockfd, message, strlen(message), 0);
}
如果您有一些协议指定何时发送消息,谁接收消息以及何时构成消息以及何时等待用户输入,则必须编写实现该协议的代码。否则,当套接字的接收缓冲区中有数据时,您将陷入scanf
中等待输入。