G
Guest
Hi all !
I have made a little server-client system based on UDP protocole. the
goal
is to communicate in an asynchronous way, if some packets are lost it's
not a problem it's why i use UDP.
The packet must be routable so I use the same port to send and receive
packet into the server and the client (same socket).
It works but I have a problem, when a client diconnected from the server
and the server try to send a packet to the client, a ICMP message error
is
receive by the server :
"WSAECONNRESET : The virtual circuit was reset by the remote side
executing a hard or abortive close. For UPD sockets, the remote host was
unable to deliver a previously sent UDP datagram and responded with a
"Port Unreachable" ICMP packet. The application should close the socket
as
it is no longer usable."
Then the server raise an error :
server.rb:12:in `recvfrom': An existing connection was forcibly closed by
the remote host. - recvfrom(2) (Errno::ECONNRESET)
This error breaks my socket and I can't anymore receive or send packet,
so
how can I ignore this error ?
Here is a very simple code for testing (it works), usually I have a
timeout system when a client don't send any packets from a certain time
but I don't include it. The client send data with a frequency of 2 Herz
and the server with a frequency of 1Herz, usually the frequency is higher
like 60Hz (for doom-like game or others).
Try to run the server and a client then diconnect the client and wathc
what there appears on the server.
server.rb :
__________________________________________
#!/usr/bin/ruby
#server
require 'socket'
s = UDPSocket::new
s.bind('', 54321)
connected_client = Array::new
while true
packet = s.recvfrom(255)
if packet[0] == 'init'
new_num_client = rand(1000)
s.send(new_num_client.to_s, 0, packet[1][3], packet[1][1])
connected_client.push(new_num_client)
Thread::new(s, packet[0], packet[1][3], packet[1][1]){|s, data, ip,
port|
puts "A new client connected"
while true
sleep(1.0)
s.send("server data", 0, ip, port)
end
}
else
data = packet[0].split('|')
puts "according to data #{data[1]} from client #{data[1]} change
some state of the server"
end
end
__________________________________________
client.rb :
__________________________________________
#!/usr/bin/ruby
#client
require 'socket'
s = UDPSocket::new
s.connect('localhost', 54321)
s.send('init', 0)
packet = s.recvfrom(255)
my_num = packet[0].to_i
Thread::new{
while true
s.send("#{my_num}|client data : #{$*[0]}", 0)
sleep(0.5)
end
}
while true
packet = s.recvfrom(255)
puts "I received server data : #{packet[0]}"
end
__________________________________________
Thanks by advance (I dont if it can be say).
Greg Burri
I have made a little server-client system based on UDP protocole. the
goal
is to communicate in an asynchronous way, if some packets are lost it's
not a problem it's why i use UDP.
The packet must be routable so I use the same port to send and receive
packet into the server and the client (same socket).
It works but I have a problem, when a client diconnected from the server
and the server try to send a packet to the client, a ICMP message error
is
receive by the server :
"WSAECONNRESET : The virtual circuit was reset by the remote side
executing a hard or abortive close. For UPD sockets, the remote host was
unable to deliver a previously sent UDP datagram and responded with a
"Port Unreachable" ICMP packet. The application should close the socket
as
it is no longer usable."
Then the server raise an error :
server.rb:12:in `recvfrom': An existing connection was forcibly closed by
the remote host. - recvfrom(2) (Errno::ECONNRESET)
This error breaks my socket and I can't anymore receive or send packet,
so
how can I ignore this error ?
Here is a very simple code for testing (it works), usually I have a
timeout system when a client don't send any packets from a certain time
but I don't include it. The client send data with a frequency of 2 Herz
and the server with a frequency of 1Herz, usually the frequency is higher
like 60Hz (for doom-like game or others).
Try to run the server and a client then diconnect the client and wathc
what there appears on the server.
server.rb :
__________________________________________
#!/usr/bin/ruby
#server
require 'socket'
s = UDPSocket::new
s.bind('', 54321)
connected_client = Array::new
while true
packet = s.recvfrom(255)
if packet[0] == 'init'
new_num_client = rand(1000)
s.send(new_num_client.to_s, 0, packet[1][3], packet[1][1])
connected_client.push(new_num_client)
Thread::new(s, packet[0], packet[1][3], packet[1][1]){|s, data, ip,
port|
puts "A new client connected"
while true
sleep(1.0)
s.send("server data", 0, ip, port)
end
}
else
data = packet[0].split('|')
puts "according to data #{data[1]} from client #{data[1]} change
some state of the server"
end
end
__________________________________________
client.rb :
__________________________________________
#!/usr/bin/ruby
#client
require 'socket'
s = UDPSocket::new
s.connect('localhost', 54321)
s.send('init', 0)
packet = s.recvfrom(255)
my_num = packet[0].to_i
Thread::new{
while true
s.send("#{my_num}|client data : #{$*[0]}", 0)
sleep(0.5)
end
}
while true
packet = s.recvfrom(255)
puts "I received server data : #{packet[0]}"
end
__________________________________________
Thanks by advance (I dont if it can be say).
Greg Burri