Reputation: 1247
The connect
method fails giving an EINVAL
when I am trying to connect from blue.example.edu
to green.example.edu
I do not get this error when I connect from blue
to blue
itself.
The Ruby documentation under connect
suggests
Errno::EINVAL - the address length used for the sockaddr is not a valid length for the address family or there is an invalid family in sockaddr
But since the same parameter is working correctly when I try connecting blue to another port on itself, this might be wrong ?
Here is the code snippet:
MY_NAME = Socket.gethostname
SERVER_NAME = "blue" # Socket.gethostname returns 'blue' on the server
SERVER_IP = Socket::getaddrinfo(SERVER_NAME, 'www', nil, Socket::SOCK_STREAM)[0][3]
#--> Gives me A.B.C.27 (see note on ipconfig below)
SERVER_LISTENING_PORT = 34900
MY_NAME = Socket.gethostname
MY_PORT_FOR_REQUESTING_SERVER = 40000
# other stuff
#CREATE
client_socket = Socket::new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
client_socket_addr = Socket.pack_sockaddr_in(MY_PORT_FOR_REQUESTING_SERVER, MY_NAME)
#BIND
client_socket.bind(client_socket_addr)
#CONNECT
server_addr = Socket.pack_sockaddr_in(SERVER_LISTENING_PORT, SERVER_NAME)
i_tried_with_ip_address_also = Socket.pack_sockaddr_in(SERVER_LISTENING_PORT, SERVER_IP)
#The line below raises the error
client_socket.connect(server_addr)
# more code below
Please note that hitting ifconfig
on blue yields the same A.B.C.27
what the SERVER_IP
contains
Under eth1 - inet addr:A.B.C.27, Bcast:A.B.C.255 Mask:255.255.255.0
I'm guessing this is related to the issue ?
Using Ruby 1.8.7 on Ubuntu machines
Please advice.
I used TCPSocket as suggested by zed_0xff in order to get this working temporarily. However I wish to know why the regular socket way is not working.
The only difference I can see is that using the Socket class, I am binding the client_socket_addr
to a port from which I wish to send my data.
TCPSocket sends data from a random port to the specified listening port on the server.
What do I do if I wish to bind the sending to a specific port ?
So the answer from @zed_0xff has helped me tackle one of my problems of actually establishing a connection between the client and the server (Thank you!)
However, with that method, TCPSocket chooses a random sending port for sending data. Trying to binding the sending port to a particular port number fails.
PS: Please let me know if modifying the question name is against the community guidelines. Since my issue was only partially resolved, I edited the title it here itself and explained the edits in the "Edit" sections.
Upvotes: 1
Views: 3277
Reputation: 452
I had the following in my specs:
url = "http://image.generator.example.com/100x100"
URI.parse(url).open
I was getting this error because the image placeholder generator had ceased working. Replacing the URL fixed things.
Upvotes: 0
Reputation: 70951
Getting EINVAL
for bind()
indicates that the address to bind to might still be in use.
To get around this
SO_REUSEADDR
on the socket prior to using itUpvotes: 2
Reputation: 33227
maybe you should try with TCPSocket instead?
require 'socket'
s = TCPSocket.new SERVER_NAME, SERVER_LISTENING_PORT
while line = s.gets # Read lines from socket
puts line # and print them
end
s.close # close socket when done
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/socket/rdoc/TCPSocket.html
Upvotes: 2