Can't bind/send data between two sockets? - python

I am trying to send packet data between two sockets using socket programming in python, basically the instructions Ive been given is to make 6 routers (im just doing two right now) and have them send packets to eachother and such, the instructions specify that I have to run the second router first then run the first (the first is the one that is reading the packets.csv file) But whenever I run the second router and then the first I get this error form the first
Traceback (most recent call last):
File "router1_skeleton.py", line 185, in <module>
socket = create_socket(host,port)
File "router1_skeleton.py", line 15, in create_socket
soc.bind((host,port))
OSError: [Errno 98] Address already in use
If I understand correctly the way to make this work is to set up the socket in router 2 which I have here
# 1. Create a socket.
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. Try connecting the socket to the host and port.
soc.bind((host,port))
soc.listen(5)
try:
conn,addr = soc.accept()
except:
print("Connection Error to", port)
sys.exit()
# 3. Return the connected socket.
return soc
And then for my first router I write
def create_socket(host, port):
# 1. Create a socket.
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. Try connecting the socket to the host and port.
soc.bind((host,port))
soc.listen(5)
try:
#print("hello")
conn,addr = soc.accept()
print("Received connection fron:", addr)
conn.send('Thank you for connecting'.encode())
except:
print("Connection Error to", port)
sys.exit()
# 3. Return the connected socket.
#print(soc)
return soc
Then I send data using soc.send(new_packet.encode())
and router 2 should be getting the data with this line and it should be working but it breaks along here
while True:
# 8. Accept the connection.
connection, address = soc.accept()
print("Accepted a connection from: ", address)
data = soc.rev(1024)
print(data.decode())
##ip, port =
print("Connected with " + ip + ":" + port)
Any suggestions are very welcome!
EDIT: Broken pipe / Transport endpoint error
if newport == 2:
print("sending packet", new_packet, "to Router 2")
socket.send(new_packet.encode())
write_to_file("output/sent_by_router_1.txt", new_packet, 2)
I use this to send the data to router 2 and this should receive it
while True:
# 8. Accept the connection.
connection, address = soc.accept()
print("Accepted a connection from: ", address)
data = soc.recv(1024)
print(data.decode())
This is the error I get
File "router1_skeleton.py", line 237, in <module>
socket.send(new_packet.encode())
BrokenPipeError: [Errno 32] Broken pipe

Related

sending json.dumps() via python sockets

What I'm trying to create are a set of server and client scripts; the server script prompts a user for raw input, stores that input in a dictionary and converts it to json with the json.dumps() function. The converted dictionary is then stored in the jasonFile variable which is then sent to the client. The json dictionary is working but I'm struggling with the networking side of things.
Here is my server code:
def Main():
host = '0.0.0.0'
port = 5000
s.bind((host, port))
s.listen(5)
print "Server Started"
while True:
addr = s.accept()
print "Client Connected from IP: " + str(addr)
serverMessage = "Connection Established: Would you like to download the Json dictionary?"
s.send(serverMessage)
clientReply = s.recv(1024)
if clientReply in ['Y', 'y', 'Yes', 'yes', 'YES']:
s.send(jasonFile)
s.close()
else:
print "Connection from " + addr + " closed!"
s.send("Connection Error!")
s.close()
And here is my client code:
def Main():
host = raw_input("Please enter the server IP you wish to connect to: ")
port = 5000
#define client to use socket module to connect via IPV4 and TCP only
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
serverMessage = client.recv(1024)
print serverMessage
clientReply = raw_input("Type 'Yes' To download dictionary")
if clientReply in ['Y', 'Yes', 'y', 'yes', 'YES']:
client.send(clientReply)
jasonRecv = client.recv(1024)
print jasonRecv
else:
client.close()
print "Disconnected from server!"
I haven't gotten as far as converting the json data back to a string on the client yet because the server throws me an error when the client tries to connect.
The error message I get from IDLE is:
Server Started
Client Connected from IP: (<socket._socketobject object at 0x000000000401E048>, ('127.0.0.1', 34375))
Traceback (most recent call last): File "D:/Server.py", line 105, in <module>
Main()
File "D:/Server.py", line 94, in Main
s.send(serverMessage)
error: [Errno 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
I thought I was defining the address to send data to in the addr variable, but apparently not?
Try:
conn, addr = s.accept()
...
conn.send(serverMessage)
i.e. replace s. calls with conn. which represents the accepted socket connection from the client.
From the Python socket API:
socket.accept()
Accept a connection. The socket must be bound to an address and listening for connections.
The return value is a pair (conn, address) where conn is a new socket
object usable to send and receive data on the connection, and address
is the address bound to the socket on the other end of the connection.
Examples are provided at the end of the page.
Also see the Python Socket Programming Howto

Python: Socket.error Connection Refused in Unix [Errno 111]

I am trying to send UDP video packets using sockets in Python.
The Server IP address is :192.168.67.14
The Client IP address is 192.168.67.42
The Client and Server can ping each other. Below is the code used for establishing the socket:
Server Side:
import urllib, time, os, m3u8
from socket import *
# Socket initialization
s = socket(AF_INET, SOCK_DGRAM)
host = "192.168.67.42"
port = 5000
buf = 1024
addr = (host, port)
s.connect((host, port))
ts_filenames = []
while True:
playlist = "https://sevenwestmedia01-i.akamaihd.net/hls/live/224853/TEST1/master_lowl.m3u8"
m3u8_obj = m3u8.load(playlist)
ts_segments = m3u8_obj.__dict__.values()[6]
ts_segments_str = str(m3u8_obj.segments)
for line in ts_segments_str.splitlines():
if "https://" in line:
ts_id = line[-20:]
if ts_id not in ts_filenames:
print ts_id
ts_filenames.append(ts_id)
try:
ts_segment = urllib.URLopener()
ts_segment.retrieve(line, ts_id)
except:
pass
f = open(ts_id, "rb")
data = f.read(buf)
while (data):
if (s.sendto(data, addr)):
print "sending ..."
data = f.read(buf)
Client Side
import socket
s = socket.socket()
host = '192.168.67.14'
port = 5000
s.connect((host,port))
print s.recv(1024)
s.close
Exception I get:
Traceback (most recent call last): File "client.py", line 7, in
s.connect((host,port)) File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args) socket.error: [Errno 111] Connection refused
I spent some time looking into this discussion but I still not sure what to modify. Any suggestions please ?
You have multiple problems here. First, by using connect on the server end, you're telling the operating system that you will only be communicating with IP address "192.168.67.42" port 5000. That is probably not what you intended. (A server usually talks to whatever client wants to talk to it.)
Second, by not specifying SOCK_DGRAM in your client, you're getting the default socket type, which is SOCK_STREAM. That means your client is trying to connect to your server on TCP port 80 -- not UDP port 80 (the two namespaces are totally separate).
For a UDP "session", both sides need an IP address and a port number. If you do not bind a port specifically, the operating system will choose one for you quasi-randomly. In order to link up client and server, they must agree on at least one of those.
So a typical UDP server will bind to a well-known port (presumably you intended 5000 for that purpose). Then the client can connect to the server at that port. The code would look something like this (sans error handling):
Server side:
# Create socket
s = socket(AF_INET, SOCK_DGRAM)
# Bind to our well known port (leave address unspecified
# allowing us to receive on any local network address)
s.bind(('', 5000))
# Receive from client (so we know the client's address/port)
buffer, client_addr = s.recvfrom(1024)
# Now we can send to the client
s.sendto(some_buffer, client_addr)
The client is close to what you have, but you should send some data from the client to the server first so that the server knows your address:
s = socket(AF_INET, SOCK_DGRAM)
# Create connection to server (the OS will automatically
# bind a port for the client)
s.connect((host, port))
# Send dummy data to server so it knows our address/port
s.send(b'foo')
buffer = s.recv(1024)
Note that because you have used connect on the client side, you've permanently specified your peer's address and don't need to use recvfrom and sendto.
On the client side, this is wrong:
s = socket.socket()
for receiving UDP packets, you need to create a UDP socket, same as you did on the server side:
s = socket(AF_INET, SOCK_DGRAM)
Also, if you want your client to be able to receive UDP packets you will need to bind() it to port 5000 (connect() is neither necessary nor sufficient for that).

Getting error while binding a socket

I am scripting a server to use at many things, gaming, data-transfer, chatting etc.
My problem is i am getting this error:
Traceback (most recent call last):
File "server.py", line 11, in <module>
s.bind((host, port))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
TypeError: an integer is required
I am at the beginning of my server script so far and i scripted many networking scripts before. There shouldnt be any problem. I tried this script both on my local and on my servers and still same resuly and the exact same error. I will really appreciate any kind of help.
Here is my code:
#!/usr/bin/python
# This is server file
import socket
# server & connection settings
host = '127.0.0.1'
port = '5002'
s = socket.socket() # Creating socket object
s.bind((host, port))
s.listen(10)
# server & connection settings
while True:
c,addr = s.accept() # Establish connection with clients.
print 'Got connection from ', addr # Print ip adress of the recently connected client.
c.send('You succesfully established connection with our servers.') # Send socket to the client.
print 'Socket had been sent to the client: ', addr # Print to the server console that we succesfully established connection with the client
c.close() # Close the client connection. Bye, bye! /// Will delete this part when the time come

error when trying to connect to server for next the connection using sockets in python

I am learning socket programming using python. my first assignment is to a write a client.py and a server.py. The client sends a message to server. The server receives the message of 16 bytes each time. After it has received the entire message, it will send the same message back to client.
so it is very simple. The server has backlog of 1. After the server sends the message to client, the connection to client close and the server should be open to receive new connection.
my current code fails in the last step. It is not open to receive new connections. It is throwing error. I even figured out the error. but I do not know how to fix this.
The error comes from server.py because I call for sock.accept() but I have closed the sock.
Let me explain my server.py code: I have two while loops. The outer loop looks for new connection, and the inner loop looks process request from connections i.e it simply receives data, wait till everything is received and send it back to client and finally close the connection.
I am asked not to change the structure of two while loops but just implement them.
Any thoughts or ideas on this:
client.py
import socket
import sys
def client(msg, log_buffer=sys.stderr):
server_address = ('localhost', 10000)
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP)
sock.connect(server_address)
print >>log_buffer, 'connecting to {0} port {1}'.format(*server_address)
try:
print >>log_buffer, 'sending "{0}"'.format(msg)
sock.sendall(msg)
chunk = ''
done=False;
while not done:
chunk+=sock.recv(16)
if chunk==msg:
done=True
print >>log_buffer, 'received "{0}"'.format(chunk)
finally:
print >>log_buffer, 'closing socket'
sock.close()
if __name__ == '__main__':
if len(sys.argv) != 2:
usg = '\nusage: python echo_client.py "this is my message"\n'
print >>sys.stderr, usg
sys.exit(1)
msg = sys.argv[1]
client(msg)
Server.py
import socket
import sys
def server(log_buffer=sys.stderr):
# set an address for our server
address = ('127.0.0.1', 10000)
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# log that we are building a server
print >>log_buffer, "making a server on {0}:{1}".format(*address)
sock.bind(address)
sock.listen(1)
try:
# the outer loop controls the creation of new connection sockets. The
# server will handle each incoming connection one at a time.
while True:
print >>log_buffer, 'waiting for a connection'
conn,add=sock.accept()
addr=(conn,add)
try:
print >>log_buffer, 'connection - {0}:{1}'.format(*addr)
# the inner loop will receive messages sent by the client in
# buffers. When a complete message has been received, the
# loop will exit
data = ''
while True:
recvdata=conn.recv(16)
print recvdata
data+=recvdata
print >>log_buffer, 'received "{0}"'.format(data)
print >>log_buffer, "len of received data: {0}".format(len(recvdata))
if len(recvdata)<16:
print >>log_buffer,"sending data"
conn.sendall(data)
break
conn.close()
finally:
sock.close()
except KeyboardInterrupt:
sock.close()
if __name__ == '__main__':
server()
sys.exit(0)
I runpython server.py in one terminal andpython client.py "This is the first message. send me back"` in a different terminal. The client connection is lost normally as expected. But I get the following error at server side (towards the end):
making a server on 127.0.0.1:10000
waiting for a connection
connection - <socket._socketobject object at 0x100849c20>:('127.0.0.1', 50626)
sairam hopefully
received "sairam hopefully"
len of received data: 16
this works lets
received "sairam hopefully this works lets"
len of received data: 16
c
received "sairam hopefully this works lets c"
len of received data: 2
sending data
waiting for a connection
Traceback (most recent call last):
File "echo_server.py", line 89, in <module>
server()
File "echo_server.py", line 39, in server
conn,add=sock.accept()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 202, in accept
sock, addr = self._sock.accept()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 170, in _dummy
raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor
You are closing sock inside your while loop. Don't do that. sock is your long-lasting server socket, which needs to remain open to listen for new connections. conn is your ephemeral socket, which needs to remain open only the length of a single connection.
Close conn after each connection, close sock when the server needs to terminate.
More simply, replace these lines:
finally:
sock.close()
with
finally:
conn.close()
What you are trying to do is a simple echo server, which I believe you can implement much more simply.
Server:
import socket
host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
client, address = s.accept()
data = client.recv(size)
if data:
client.send(data)
client.close()
Client:
import socket
host = 'localhost'
port = 50000
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.send('Hello, world')
data = s.recv(size)
s.close()
print 'Received:', data

Setting up non-blocking socket for Jython for use in Chat server

I'm trying to create a Jython(actually monkeyrunner) program which receives messages from other python(CPython because it uses OpenCV)
First, I tried to implement a chatting program example(server-side) and I ran into a problem.
While the example uses Blocking-socket for select, the Jython select cannot support it.
Therefore, I put the code 'server_socket.setblocking(0)' when setting the socket, but nothing changed.
Also, I tried 'from select import cpython_compoatible_select as select', but it causes Attribute error, 'function' object has no attribute 'select'.
Below is my code
# coding: iso-8859-1
import socket,select
#Function to broadcast chat messages to all connected clients
def broadcast_data (sock, message):
#Do not send the message to master socket and the client who has send us the message
for socket in CONNECTION_LIST:
if socket != server_socket and socket != sock :
try :
socket.send(message)
except :
# broken socket connection may be, chat client pressed ctrl+c for example
socket.close()
CONNECTION_LIST.remove(socket)
if __name__ == "__main__":
# List to keep track of socket descriptors
CONNECTION_LIST = []
RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2
PORT = 5000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# this has no effect, why ?
#JYTHON never supports blocking-mode socket so make it unblock
server_socket.setblocking(0)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(("0.0.0.0", PORT))
server_socket.listen(10)
# Add server socket to the list of readable connections
CONNECTION_LIST.append(server_socket)
print "Chat server started on port " + str(PORT)
while 1:
# Get the list sockets which are ready to be read through select
#JYTHON never supports blocking-mode socket so make it unblock
server_socket.setblocking(0)
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])
for sock in read_sockets:
#New connection
if sock == server_socket:
# Handle the case in which there is a new connection recieved through server_socket
#JYTHON never supports blocking-mode socket so make it unblock
server_socket.setblocking(0)
sockfd, addr = server_socket.accept()
CONNECTION_LIST.append(sockfd)
#print "Client (%s, %s) connected" % addr
broadcast_data(sockfd, "[%s:%s] entered room\n" % addr)
#Some incoming message from a client
else:
# Data recieved from client, process it
try:
#In Windows, sometimes when a TCP program closes abruptly,
# a "Connection reset by peer" exception will be thrown
data = sock.recv(RECV_BUFFER)
if data:
print data
broadcast_data(sock, "\r" + '<' + str(sock.getpeername()) + '> ' + data)
except:
broadcast_data(sock, "Client (%s, %s) is offline" % addr)
print "Client (%s, %s) is offline" % addr
sock.close()
CONNECTION_LIST.remove(sock)
continue
server_socket.close()
#see http://www.binarytides.com/code-chat-application-server-client-sockets-python/
and my error message
C:\NVPACK\android-sdk-windows\tools\lib>monkeyrunnerUTF chatserver.py
Chat server started on port 5000
130815 17:06:17.418:S [MainThread] [com.android.monkeyrunner.MonkeyRunnerOptions
] Script terminated due to an exception
130815 17:06:17.418:S [MainThread] [com.android.monkeyrunner.MonkeyRunnerOptions
]Traceback (most recent call last):
File "C:\NVPACK\android-sdk-windows\tools\chatserver.py", line 41, in <module>
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],
[])
File "C:\NVPACK\android-sdk-windows\tools\lib\jython-standalone-2.5.3.jar\Lib\
select.py", line 225, in native_select
File "C:\NVPACK\android-sdk-windows\tools\lib\jython-standalone-2.5.3.jar\Lib\
select.py", line 106, in register
select.error: (20000, 'socket must be in non-blocking mode')
Thank you in advance :)
AndroidViewClient's tests implement a MockViewServer using monkeyrunner, setting the socket as non-blocking and using
from select import cpython_compatible_select as select
for select.
See the source code at https://github.com/dtmilano/AndroidViewClient/blob/master/AndroidViewClient/tests/com/dtmilano/android/mocks.py#L758
This works on Linux and OSX (your mileage may vary with Windows)

Categories