Reputation: 45
I am making socket programming for simple communication now.
I have noticed that the server is not the one I created and it works fine (given the experimental client)
In my code, recv works fine, but send does not work. Is there anything wrong with my code?
my $socket = new IO::Socket::INET (
#PeerHost => '127.0.0.1',
PeerHost => '192.168.0.100',
PeerPort => '8472',
Proto => 'tcp',
);
die "cannot connect to the server $!\n" unless $socket;
print "connected to the server\n";
while (1) {
my $response = "";
$socket->recv($response, 1024);
if ($response) {
my @test = split(//,$response);
my ($length,$data) = unpack("N A*",$response);
%json = json_decode($data,$length);
switch ($json{'type'}) {
case 1 { print "Game Start\n";}
#case 2 { my $tmp = &my_turn(%json);} #my_turn func is return "{'type': 0, 'point': [5, 4]}", but fail!
#case 2 { $socket->send("{'type': 0, 'point': [5, 4]}");} # fail!
case 2 { print $socket "{'type': 0, 'point': [5, 4]}"; print "ok\n";} # print is executed. However, the server does not receive packets
#case 2 { $socket->send("{'type': 0, 'point': [5, 4]}");} #fail...
case 3 { print "ACCEPT\n";}
case 5 { print "NOPOINT\n";}
case 6 { print "GAMEOVER\n";}
case 7 { print "ERROR\n";}
else {print "ERROR type : $json{'type'}\n"}
}
}
}
The server works fine. I checked with the example source (python code) given with the server. What am I missing?
Upvotes: 1
Views: 806
Reputation: 5972
recv
(or read
) will return the entire response. You need to call it repeatedly.recv
(or read
) will just the response. You need to limit the size of the read of buffer the excess.decode_json
returns a reference (not a list of key-value pairs you can assign to a hash).case 2
in the original code) needs to include length too.The following code should be used instead:
#!/usr/bin/perl
use strict;
use warnings;
use JSON;
use IO::Socket;
my $socket = IO::Socket::INET->new(
PeerHost => '127.0.0.1',
PeerPort => '22',
Proto => 'tcp',
) or
die "cannot connect to the server $!\n";
print "connected to the server\n";
sub read_bytes($$) {
my($socket, $length) = @_;
my $result = '';
print "ATTEMPT TO READ ${length}\n";
while ($length > 0) {
my $received = $socket->read($result, $length, length($result));
die "socket error: $!\n" unless defined($received);
die "unexpected EOF\n" unless $received;
$length -= $received;
}
print "READ '${result}'\n";
return($result);
}
while (1) {
my $length = unpack("N", read_bytes($socket, 4));
my $json = read_bytes($socket, $length);
my $data = JSON->new->utf8->decode($json);
print $data->{type}, "\n";
if ($data->{type} == 2) {
my $response = {
type => 0,
point => [5, 4],
};
my $resp_json = JSON->new->utf8->encode($response);
print "JSON: ${resp_json}\n";
my $packet = pack('NA*', length($resp_json), $resp_json);
print "PACKET: ", unpack('H*', $packet), "\n";
$socket->write($packet);
}
}
As I don't have access to your server I used sshd
on my local machine, which of course does not send me a JSON. But it shows that reading works :-)
$ perl dummy.pl
connected to the server
ATTEMPT TO READ 4
READ 'SSH-'
ATTEMPT TO READ 1397966893
^C
Output for an example response to the server would be:
JSON: {"type":0,"point":[5,4]}
PACKET: 000000187b2274797065223a302c22706f696e74223a5b352c345d7d
Upvotes: 2