【发布时间】:2014-08-13 19:42:43
【问题描述】:
我有一个 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
根据我的输出,写入客户端成功。但是当在 recv 方法中调用 socket.gets 时,我的 ruby 客户端挂起。我也尝试过使用 socket.read 并且也挂起。我只需要从我的服务器获取第一个字节或一行输入。
为什么我的客户端不能从我的服务器接收输入?
应该发生的事情的清单是:
- 服务器已启动
- 客户端启动,用户输入用户名和密码
- 服务器收到用户名和密码
- 服务器向客户端发送字符串
- 客户端从服务器接收字符串
- 客户端根据字符串做一些操作
client.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 代码以反映我现在所拥有的内容。我将 send 方法中的 strlen(input) 参数更改为 strlen(ch)。问题仍然存在。
我已经通过 telnet 测试了我的服务器,结果是一样的。我可以写入我的服务器,但不能从中读取。这让我相信我的 Ruby 客户端没有任何问题。这一定是我的服务器发送数据的方式有问题。
【问题讨论】:
标签: c ruby sockets networking client-server