1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
use IO::Select;
#$/ = "\r";
print "Server: Starting server\n";
my $port = 12345;
my $host = "localhost";
my $CTIME_String = localtime(time);
my $listen_socket = IO::Socket::INET->new( Listen => 1,
LocalPort => $port,
LocalHost => $host,
Proto => 'tcp',
Blocking => 0,
) or die "Error during creation of listening socket: $!\n";
my $select = new IO::Select($listen_socket);
print "Server: Waiting for client connection on port $port\n";
while (my @ready = $select->can_read)
{
foreach my $connection (@ready)
{
if ($connection == $listen_socket)
{
my $client = $listen_socket->accept();
print "Server: Client $client accepted\n";
$select->add($client);
}
else
{
my $data='';
$data = <$connection>;
if ($data)
{
$CTIME_String = localtime(time);
print "Server: Received: $CTIME_String: $data";
#$connection->send("SERVER: " . $data);
}
else
{
print "Server: Closing connection to $connection\n";
$select->remove($connection);
close($connection);
}
}
}
}
Quoteb) naja, wenn eine Zeile gelesen werden soll (noch dazu ohne Timeout) wird natürlich erstmal blockiert. Ich denke, alarm beim Lesen wäre eine Möglichkeit. Außerdem vielleicht nicht mit <$connection>, sondern manuell lesen, was kommt (mit getc oder wie auch immer), dann könntest Du auch Teile von Zeilen mitbekommen (aber timeouts solltest Du dennoch haben).
while (my @ready = $select->can_read)
$lesepuffer{$client} ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
while (1)
{
foreach my $connection (my @can_read = $select->can_read(5))
{
if ($connection == $listen_socket)
{
my $client = $listen_socket->accept();
$select->add($client);
$client->recv($data,1024);
if ($data) {
my @received = unpack('C*', $data);
my $id=join('', map {sprintf('%02x', $_)} @received);
if (exists($con_hash{ $id })) {
if ($con_hash{ $id } != $client) {
&do_log("ID $id changed socket from $con_hash{ $id } to $client, updating entry");
$con_hash{ $id }=$client;
}
else {
&do_log("ID $id re-connected on same socket $client");
}
}
else {
if ($id) {
&do_log("Creating connection entry for ID $id");
$con_hash{ $id }=$client;
while( my ($k, $v) = each %con_hash ) {
&do_log ("Connected ID: $k, socket: $v");
}
}
else {
&do_log("ERROR: Something is wrong");
}
}
}
else {
&do_log("ERROR: Something else is wrong");
}
}
else
{
&do_log("Closing connection to $connection");
while( my ($key, $value) = each %con_hash ) {
if ($value == $connection) {
&do_log("Deleting connection entry for ID $key");
delete $con_hash{$key};
}
}
while( my ($k, $v) = each %con_hash ) {
&do_log ("Connected ID: $k, socket: $v");
}
$select->remove($connection);
close($connection);
}
}
foreach my $connection (my @can_write = $select->can_write(5))
{
my @send_dec=qw(T E S T);
my $send_hex=pack('C*', @send_dec);
while( my ($con_id, $sock) = each %con_hash ) {
&do_log("Sending data to ID $con_id via socket $sock: ".join('', map {sprintf('%02x', $_)} @send_dec));
$sock->send($send_hex);
$sock->recv($data,1024);
my @recv_dec = unpack('C*', $data);
&do_log("Received data from ID $con_id via socket $sock: ".join('', map {sprintf('%02x', $_)} @recv_dec));
}
}
sleep (5);
}
2012-11-26T13:24:59 montiedit: Ich sehe keinen Debugoutput vor dem sleep. Ich verstehs nicht....
while (defined(my $conn = $socket->accept)) {
QuoteIch hab doch die ID als key und das socket als Value, dachte ich bisher....