gpt4 book ai didi

c - Ruby 客户端无法从 C 服务器读取 : socket. 挂起

转载 作者:太空宇宙 更新时间:2023-11-04 04:42:13 25 4
gpt4 key购买 nike

我有一个 C 语言的服务器和一个 Ruby 语言的客户端。我的 ruby​​ 客户端能够成功地将一个字符串发送到我的 C 服务器,但它无法从它接收任何输入。

更具体地说,我在 client.rb 中的“recv”方法中的“gets”方法挂起。启动我的 client.rb 程序如下所示:

[user]$ ruby client.rb
## CLIENT STARTED ##
user: myuser //user enters username and password here
password: mypass // It hangs after this line, so I press ctrl-C

^Cclient.rb:27:in `gets': Interrupt //This is the output after pressing ctrl-C
from client.rb:27:in `verifyUser'
from client.rb:40:in `main'
from client.rb:48

虽然我的服务器的输出是:

## SERVER STARTED ##
[Wed Aug 13 12:19:43 2014] 21 bytes 0 myuser mypass
write succeed
request processed

根据我的输出,写入客户端成功。但是我的 ruby​​ 客户端在 recv 方法中调用 socket.gets 时挂起。我也尝试过使用 socket.read 并且它也挂起。我只需要从我的服务器获取第一个字节或一行输入。

为什么我的客户端不能从我的服务器接收输入?

应该发生的事情列表是:

  • 服务器启动
  • 客户端启动,用户输入用户名和密码
  • 服务器收到用户名和密码
  • 服务器向客户端发送字符串
  • 客户端从服务器接收字符串
  • 客户端根据字符串做一些操作

客户端.rb

$ip = '127.0.0.1'
$port = 29008

def send(msg)
socket = TCPSocket.new($ip, $port)
socket.write(msg)
socket.close
end

def recv
socket = TCPSocket.new($ip, $port)
data = socket.gets
socket.close
data
end

def verifyUser(user, pw)
send("0 #{user.chomp!} #{pw.chomp!}")
recv =~ /^0/
end


def main

puts "## CLIENT STARTED ##"
print "user: "
user = gets
print "password: "
pw = gets

if verifyUser(user, pw) then
puts "user verified"
else
puts "wrong user or password"
end

end

main

server.c

/* PROCESS REQUEST */
void processRequest(char *input, int cfd) {

int option = 0;
char *ch = "0";

if (option == 0) {

if (send(cfd, ch, strlen(ch), 0) < 0) {
puts ("write error");
} else {
puts ("write succeed");
}

} else {
puts("option is not valid");
}
}



int main() {

int sfd, cfd;
int optval = 1;
char buffer[2000];
char input[2000];
int len;
int idx = 0;
time_t currTime;
char *time_str;


struct sockaddr_in saddr, caddr;


sfd = socket(AF_INET, SOCK_STREAM, 0);


saddr.sin_family = AF_INET; /* Set address family to IPv4 Internet */
saddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any internet address */
saddr.sin_port = htons(29008); /* Set server port to 29008 */

setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);

bind(sfd, (struct sockaddr *)&saddr, sizeof(saddr));


listen(sfd, 1);

printf("## SERVER STARTED ##\n");

while (1) {



if ((cfd = accept(sfd, (struct sockaddr *)NULL, NULL)) < 0) {
puts("client connection failed");
}

/* get time of message */
currTime = time(NULL);
time_str = asctime(localtime(&currTime));
time_str[strlen(time_str) - 1] = '\0';


/* ensure that all everything is received from client */
while ((len = recv(cfd, buffer, 2000, 0)) > 0) {

buffer[len] = '\0';

if (idx == 0) {
strcpy(input, buffer);
} else {
strcat(input, buffer);
}

/* log message */
printf ("[%s] %d bytes %s\n", time_str, len, input);

idx++;
}

if (len < 0) {
printf("recieve failed\n");
return 1;
}

processRequest(input,cfd);
puts("request processed");


close(cfd);

idx = 0;
input[0] = '\0';
}

return 0;
}

编辑

  • 我修改了 server.c 代码以反射(reflect)我现在拥有的内容。我将发送方法中的 strlen(input) 参数更改为 strlen(ch)。问题仍然存在。

  • 我已经通过 telnet 测试了我的服务器,结果是一样的。我可以写入我的服务器,但不能从中读取。这使我相信我的 Ruby 客户端没有任何问题。这一定是我的服务器发送数据的方式有问题。

最佳答案

修改后的答案:

1) 在 ruby​​ 代码中,您没有使用相同的套接字从服务器写入和读取。在 verifyUser 中创建套接字并将其传递到 send/recv - 这样您就可以保持与服务器的连接。

def send(s, msg)
print("sending: '" + msg + "'\n")
s.write(msg)
s.flush
end

def recv(s)
print("in recv");
data = s.recv(1024)
print("got data: " + data);
data
end

def verifyUser(user, pw)
socket = TCPSocket.new($ip, $port)
send(socket,"0 #{user.chomp!} #{pw.chomp!}\0")
resp = recv(socket)
socket.close
resp =~ /^0/
end

2) 在 c 服务器中 - len = recv while 循环 - 你真的需要 while 循环吗?服务器读取命令并再次循环。它之前工作的唯一原因是因为您关闭了套接字,然后 recv 出现错误,跳出循环并处理了请求。如果将 processRequest 放在带有时间戳的 printf 下,您会看到服务器确实发送了响应。如果你整理出 ruby​​ 客户端套接字的东西,你实际上会得到那个响应。

关于c - Ruby 客户端无法从 C 服务器读取 : socket. 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25294782/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com