TCP Python Socket Server Response - python

I'm writing a TCP python script that will act as a server and retrieve a temperature reading from a machine (the client). I need to pass a command to the client from the server and listen for an output of the response. I successfully reach the cmd definition line, but when s.accept() is called I'm left hanging with no response from the client.
Server.py
import socket
port = 7777
ip = raw_input('192.168.62.233')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((ip, port))
s.listen(1)
print "waiting on port: ", port
while True:
cmd = raw_input('KRDG? A[term]')#command send to client
conn, addr = s.accept()
s.send(cmd)
print "It sent"
data = conn.recv(4096)
print "Received:", data, " from address ", addr
Edit:
I believe you're correct, I should consider my code the client and temperature readout at the server. I do now get left hanging after "here 2" when I go to s.recv().
Client.py
import socket
ip = '192.168.62.233'
port = 7777 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
print 'here'
s.send('KRDG? A[term]')
print 'here 2'
data = s.recv(4096)
print 'here 3'
s.close()
print 'Received', repr(data)

Usually, a TCP server accept will block while it waits for a client to connect. Have you checked to make sure that you client can and is connecting? You could use a tool like tcpdump or similar to watch the network activity and make sure the client is connecting.

Related

weird movement socket based programming [duplicate]

I copied the echo server example from the python documentation and it's working fine. But when I edit the code, so it wont send the data back to the client, the socket.recv() method doesn't return when it's called the second time.
import socket
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(b'ok')
conn.close()
In the original version from the python documentation the while loop is slightly different:
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
Client's code:
import socket
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
s.close()
print('Received', repr(data))
TCP sockets are streams of data. There is no one-to-one correlation between send calls on one side and receive calls on the other. There is a higher level correlation based on the protocol you implement. In the original code, the rule was that the server would send exactly what it received until the client closed the incoming side of the connection. Then the server closed the socket.
With your change, the rules changed. Now the server keeps receiving and discarding data until the client closes the incoming side of the connection. Then the server sends "ok" and closes the socket.
A client using the first rule hangs because its expecting data before it closes the socket. If it wants to work with this new server rule, it has to close its outgoing side of the socket to tell the server its done, and then it can get the return data.
I've updated the client and server to shutdown parts of the connection and also have the client do multiple recv's in case the incoming data is fragmented. Less complete implementations seem to work for small payloads because you are unlikely to get fragmentation, but break horribly in real production code.
server
import socket
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()
client
import socket
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
s.shutdown(socket.SHUT_WR)
data = b''
while True:
buf = s.recv(1024)
if not buf:
break
data += buf
s.close()
print('Received', repr(data))
The number of receive and send operations have to match because they are blocking. This is the flow diagram for your code:
Server listen
Client connect
Server receive (this waits until a message arrives at the server) [1]
Client send 'Hello world' (received by [1])
Server receive (because there was data received) [2]
Client receive [3]
Because the server and the client are blocked now, no program can continue any further.
The fix would be to remove the client's receive call because you removed the server's send call.

Python Socket, how do i choose between s.send and conn.send?

def send_Button():
try:
myMsg = "ME: " + text.get()
msg = text.get()
conn.send(msg) ###
textBox.insert(END, myMsg + "\n")
textEntry.delete(0, END)
textBox.yview_pickplace("end")
except NameError:
myMsg = "ME: " + text.get()
msg = text.get()
conn.send(msg) ###
textBox.insert(END, myMsg + "\n")
textEntry.delete(0, END)
textBox.yview_pickplace("end")
This program uses the tkinter module with socket in python2.7. My program allows for you to either connect to a server to chat with or host a server for others to connect to you, but whenever I try and test it out then the lines with the '###' on always bring up an error and it doesn't work, the error which comes up is: "NameError: global name 'conn' is not defined" OR "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".
Any help please?
I think that you are trying to get the program to act as a Client or as a Server just changing s.send() to conn.send() saddly it isn't that simple.
Socket Initializzation
The socket have to be initialized before sending or receiving data.
For a client usually it's something like this.
send_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # Create the socket
send_socket.connect((serverIp, serverPort)) # Connect to the server
send_socket.send(data) # Send the data to the server
And like this for a Server:
listen_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # Create the socket
listen_socket.bind(("0.0.0.0", port)) # Set the socket to accept client from every interface on the port port
listen_socket.listen(1) # Put the server on listen on the port setted before
accept_socket, addr = self.listen_socket.accept() # when a client connect return the socket to talk with it
data = self.accept_socket.recv(buffer_size) # Receive data form the client of max size buffer_size
Docs examples
From your question I guess that with s.send() and conn.send() you are talking about
this example from the python 2.7 socket docs
Here are four minimal example programs using the TCP/IP protocol: a server that echoes all data that it receives back (servicing only one client), and a client using it. Note that a server must perform the sequence socket(), bind(), listen(), accept() (possibly repeating the accept() to service more than one client), while a client only needs the sequence socket(), connect(). Also note that the server does not sendall()/recv() on the socket it is listening on but on the new socket returned by accept().
Client
Echo client program
import socket
HOST = 'daring.cwi.nl' # The remote host
PORT = 50007 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)
the client is pretty stright forward, it create the socket s and then after using s.connect() it just send data through it.
Server
The server one is where there there are both s and conn
Echo server program
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
conn.close()
in this one first of all we create a socket s on which the server will listen and then using s.accept() it will wait till a client connect to the server and then return the conn which is the socket of the connected client.
So to receive or send data to the client you have to use conn.
Notes
As said in the documentation in these two example the server accept only one client. So if you want to deal with multiple clients you have to repeat the accept step and possibly generate a new Thread for each client so that other clients don't have to wait for each others.

Python Socket communication across networks not working

I'm trying to set up communication between me and my friend's computer using the socket module. I run the server code on my computer and he runs the client code on his computer. Here is the code:
Server:
import socket
host = "XXX.XXX.XX.XXX" # IP of my computer
port = 2000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
addrs = []
print("Server started")
while True:
data, addr = s.recvfrom(1024)
if not addr in addrs:
addrs.append(addr)
data = data.decode("utf-8")
print("Recieved: " + str(data))
print("Sending: " + data)
for add in addrs:
s.sendto(data.encode("utf-8"), add)
Client:
import socket
import time
host = "XXX.XXX.XXX.XXX" # External IP of my router
port = 2001
server = (host, port)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setblocking(False)
while True:
message = "Test message"
time.sleep(1)
print("Sending: " + message)
s.sendto(message.encode("utf-8"), server)
try:
data, addr = s.recvfrom(1024)
except BlockingIOError:
pass
else:
data = data.decode("utf-8")
print("Recieved: " + str(data))
Note: The port in the client vs. server code is different to make sure that my port forwarding is actually doing something.
I have set up port forwarding on my router. Everything works fine when I run both scripts on my computer (or even another computer connected to the same WiFi as mine) and I know that the port forwarding is doing its thing. However, when my friend (who is connected to a different WiFi) runs the client code, it doesn't work. No error is thrown, but he sends data which neither my computer nor the router's port forwarding rule recieves.
Could this problem originate from my code, or is it more likely to be because of my router not being properly set up?
Okay I setup a HotSpot my Android Phone. which in this case is your "Router", used my phone's IP Address. and On the computer tried to run your client code, its sending test messages on the client:
Sending: Test message
Sending: Test message
Sending: Test message
Sending: Test message
....
but I'm receiving nothing on your Server, still saying server started.
so I configured your host variable on the "Client App" like so, also your ports are not consistent 2000 on server and 2001 on client:
host = "" # External IP of my router
port = 2000
NOTE!! I left the host Empty
Because I think for some reason the server is hosted locally on the pc, you are running the server on. This way i can also Connect locally from the same computer I ran the server app with:
host = "localhost" # External IP of my router
on the your client app.
this is how everything looks.
Server Code
run this on your comuter.
import socket
host = "" # IP of my computer
port = 2000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
addrs = []
print("Server started")
while True:
data, addr = s.recvfrom(1024)
if not addr in addrs:
addrs.append(addr)
data = data.decode("utf-8")
print("Recieved: " + str(data))
print("Sending: " + data)
for add in addrs:
s.sendto(data.encode("utf-8"), add)
Depending on where you ran your serverApp. use the IP of the computer running the server. I'm Still learning so I don't know how to set it up to use your router's IP.
ClientApp Code
run this on your friend computer or more. or on android even.
import socket
import time
host = "ip_of_the_computer_the_server_is_running_on" # connecting from another computer
#host = "localhost" # If you connecting locally
port = 2000
server = (host, port)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setblocking(False)
while True:
message = "Test message"
time.sleep(1)
print("Sending: " + message)
s.sendto(message.encode("utf-8"), server)
try:
data, addr = s.recvfrom(1024)
except BlockingIOError:
pass
else:
data = data.decode("utf-8")
print("Recieved: " + str(data))
And use Your router only for same AP Connection.
Tested with my TOTO-LINK IT WORKS FINE. as long as I don't use my router's IP On the client host.
Demonstrations
Server
CLient
Client On Mobile
This code is actually 100% correct, the error was in my port forwarding.

Connecting client and server in python the code below dont give output make browser busy

This code is not giving output it just makes the browser busy. Any idea why?
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.connect(('127.0.0.1', port))
print (s.recv(1024))
s.close
import socket
s=socket.socket()
host = socket.gethostname()
port = 12345
s.bind(('127.0.0.1', port))
s.listen(5)
while True:
c,addr = s.accept()
print ('Got connection from', addr)
c.send('Thank you for connecting')
c.close()
client program:
import socket
f=open("hello.txt","r").read()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 12345
s.connect(('127.0.0.1', port))
s.sendall(str.encode(f))
print (s.recv(1024).decode('ascii'))
s.close()
server program:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ("Socket successfully created")
port = 12345
s.bind(('', port))
print ("socket binded to %s" %(port))
f=open("hi.txt","r").read()
s.listen(5)
print ("socket is listening")
while True:
c, addr = s.accept()
print ('Got connection from', addr)
print (c.recv(1024).decode('ascii'))
c.sendall(str.encode(f))
c.close()
server output:
Socket successfully created
socket binded to 12345
socket is listening
Got connection from ('127.0.0.1', 51630)
helloooooo
client output:
hiiiii
Open the two programs in seperate shells.
Run server program first then client program.
Dont close the server program before running client program.
Create two files one for server and one for client.
Read the data from those files and send it.
While receiving the data decode it and print it.
You can send entire data from files or just a single line it depends on you.
To know more about reading,writing and creating files you can refer https://docs.python.org/release/3.6.5/tutorial/inputoutput.html#reading-and-writing-files
Let me know if it worked :)

Sending string via socket (python)

I have two scripts, Server.py and Client.py.
I have two objectives in mind:
To be able to send data again and again to server from client.
To be able to send data from Server to client.
here is my Server.py :
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.3"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))
serversocket.listen(5)
print ('server started and listening')
while 1:
(clientsocket, address) = serversocket.accept()
print ("connection found!")
data = clientsocket.recv(1024).decode()
print (data)
r='REceieve'
clientsocket.send(r.encode())
and here is my client :
#! /usr/bin/python3
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host ="192.168.1.3"
port =8000
s.connect((host,port))
def ts(str):
s.send('e'.encode())
data = ''
data = s.recv(1024).decode()
print (data)
while 2:
r = input('enter')
ts(s)
s.close ()
The function works for the first time ('e' goes to the server and I get return message back), but how do I make it happen over and over again (something like a chat application) ?
The problem starts after the first time. The messages don't go after the first time.
what am I doing wrong?
I am new with python, so please be a little elaborate, and if you can, please give the source code of the whole thing.
import socket
from threading import *
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.3"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))
class client(Thread):
def __init__(self, socket, address):
Thread.__init__(self)
self.sock = socket
self.addr = address
self.start()
def run(self):
while 1:
print('Client sent:', self.sock.recv(1024).decode())
self.sock.send(b'Oi you sent something to me')
serversocket.listen(5)
print ('server started and listening')
while 1:
clientsocket, address = serversocket.accept()
client(clientsocket, address)
This is a very VERY simple design for how you could solve it.
First of all, you need to either accept the client (server side) before going into your while 1 loop because in every loop you accept a new client, or you do as i describe, you toss the client into a separate thread which you handle on his own from now on.
client.py
import socket
s = socket.socket()
s.connect(('127.0.0.1',12345))
while True:
str = raw_input("S: ")
s.send(str.encode());
if(str == "Bye" or str == "bye"):
break
print "N:",s.recv(1024).decode()
s.close()
server.py
import socket
s = socket.socket()
port = 12345
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print "Socket Up and running with a connection from",addr
while True:
rcvdData = c.recv(1024).decode()
print "S:",rcvdData
sendData = raw_input("N: ")
c.send(sendData.encode())
if(sendData == "Bye" or sendData == "bye"):
break
c.close()
This should be the code for a small prototype for the chatting app you wanted.
Run both of them in separate terminals but then just check for the ports.
This piece of code is incorrect.
while 1:
(clientsocket, address) = serversocket.accept()
print ("connection found!")
data = clientsocket.recv(1024).decode()
print (data)
r='REceieve'
clientsocket.send(r.encode())
The call on accept() on the serversocket blocks until there's a client connection. When you first connect to the server from the client, it accepts the connection and receives data. However, when it enters the loop again, it is waiting for another connection and thus blocks as there are no other clients that are trying to connect.
That's the reason the recv works correct only the first time. What you should do is find out how you can handle the communication with a client that has been accepted - maybe by creating a new Thread to handle communication with that client and continue accepting new clients in the loop, handling them in the same way.
Tip: If you want to work on creating your own chat application, you should look at a networking engine like Twisted. It will help you understand the whole concept better too.

Categories