In socket, I found that if server does not send any message before call recv(), server will be no response, whatever using mutilthread or not.
As the figure shows below:
enter image description here
enter image description here
server.py(Using SocketServer module):
def handle(self):
conn = self.request
# conn.send('Welcome to server')
flag = True
while flag:
data = conn.recv(1024)
print 'client:' + data
if data == 'exit':
flag = False
conn.send('AAAAAA')
conn.close()
client.py:
client = socket.socket()
ip_port = ('127.0.0.1', 11111)
client.connect(ip_port)
while True:
data = client.recv(1024)
print 'server:' + data
send = raw_input('client:')
client.send(send)
if send == 'exit':
sys.exit()
I would appreciate it very much if you would help me with it.
# server.py
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5005
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connection address:', addr
while 1:
data = conn.recv(BUFFER_SIZE)
if not data: break
print "Server received data:", data
conn.send("Data received at server side")
conn.close()
# client.py
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
print "Client: " + MESSAGE
data = s.recv(BUFFER_SIZE)
s.close()
print data
I think providing a sample code could speak itself.
# Expected input:
python server.py
python client.py
# Expected output:
# (server output)
Connection address: ('127.0.0.1', 62136)
Server received data: Hello World!
# (client output)
Client: Hello World!
Data received at server side
You could find out your missing component by comparing the code,such as bind().
Hope it help.
With reference to this site: https://wiki.python.org/moin/TcpCommunication
Related
Below are my three scripts. I need to send the message from sricpt 1(Sensor.py) to script 2.(Client.py). And then the script 2 should send the message to script 3(Server.py).
It works fine till script 2 but the message isn't being received at the script 3 and the recvfrom() keeps waiting. There is no error but the script 3 doesn't show the message. Im using UDP. Please help.
SCRIPT 1(Sensor.py)
from socket import *
from time import ctime
CLIENT_IP = '192.168.1.109'
PORT = 23567
BUFSIZE = 1024
ADDR = (CLIENT_IP, PORT)
udpCliSock = socket(AF_INET, SOCK_DGRAM)
while True:
sendData = input("> ")
if sendData is None:
break
udpCliSock.sendto(sendData.encode(), ADDR)
udpCliSock.close()
SCRIPT 2(Client.py)
from socket import *
from time import ctime
HOST = '192.168.1.103'
CLIENT_IP='192.168.1.109'
PORT = 5005
SENSOR_PORT_NO=23567
BUFSIZE = 1024
ADDR = (HOST, PORT)
CLIENT_ADDR=(CLIENT_IP,SENSOR_PORT_NO)
udpCliSock = socket(AF_INET, SOCK_DGRAM)
client = socket(AF_INET, SOCK_DGRAM)
client.bind(CLIENT_ADDR)
while True:
print("...waiting for response...")
#recv_data, ADDR = udpCliSock.recvfrom(BUFSIZE)
recv_data, ADDR = client.recvfrom(1024)
if recv_data is not None:
recv_data = recv_data.decode()
print("[%s]: receiving data from server %s:%s :%s" % (ctime(),ADDR[0], ADDR[1], recv_data))
sendData = recv_data
udpCliSock.sendto(sendData.encode(), ADDR)
udpCliSock.close()
SCRIPT 3(Server.py)
from socket import *
from time import ctime
HOST = '192.168.1.103'
PORT = 5005
BUFSIZE = 1024
ADDR = (HOST, PORT)
udpSerSock = socket(AF_INET, SOCK_DGRAM)
udpSerSock.bind(ADDR)
while True:
print("...waiting for message...")
data, ADDR = udpSerSock.recvfrom(BUFSIZE)
print(data.decode)
if data is None:
break
print("[%s]: From Address %s:%s receive data: %s" % (ctime(),ADDR[0],ADDR[1], data.decode()))
udpSerSock.close()
The problem is that, in the Client.py, you are overwriting the address of the server when you receive the datagram from the sensor. Here:
recv_data, ADDR = client.recvfrom(1024)
ADDR starts out with the server's socket address, but this function overwrites that variable with the sensor's socket address. So when you try to send, you're sending it back to the sensor (who of course isn't ever receiving it).
A better method is to connect that socket to the server at the beginning. Then you can just use send instead of sendto since the address won't be changing. Should work after that:
...
udpCliSock = socket(AF_INET, SOCK_DGRAM)
udpCliSock.connect(ADDR) # <<<<<<===============
client = socket(AF_INET, SOCK_DGRAM)
client.bind(CLIENT_ADDR)
while True:
print("...waiting for response...")
recv_data, addr = client.recvfrom(1024)
if recv_data is not None:
recv_data = recv_data.decode()
print("[%s]: receiving data from server %s:%s :%s" % (ctime(),addr[0], addr[1], recv_data))
sendData = recv_data
udpCliSock.send(sendData.encode()) # <<<<<<===============
udpCliSock.close()
I've made a code which is able to receive data from the port over TCP protocol. I receive data from ESP8266 every 15 minutes, and then ESP goes to a deepSleep mode. How to change it to make it work continuosly? I wanted to create a new connection in while loop, but it doesn't work.
My code
import sys
import socket
TCP_IP = '192.168.42.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []
i=0
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((TCP_IP,TCP_PORT))
#s.listen(1)
#print 'Listening for client...'
#conn, addr = s.accept()
#print 'Connection address:', addr
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP,TCP_PORT))
s.listen(1)
print 'Listening for client...'
conn, addr = s.accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if data == ";" :
conn.close()
print "Received all the data"
i=0
for x in param:
print x
#break
elif data:
print "received data: ", data
param.insert(i,data)
i+=1
#print "End of transmission"
EDIT:
My code after modification.
import sys
import socket
TCP_IP = '192.168.42.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []
i=0
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((TCP_IP,TCP_PORT))
#s.listen(1)
#print 'Listening for client...'
#conn, addr = s.accept()
#print 'Connection address:', addr
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP,TCP_PORT))
s.listen(1)
while 1:
print 'Listening for client...'
conn, addr = s.accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if data == ";" :
conn.close()
print "Received all the data"
i=0
for x in param:
print x
#break
elif data:
print "received data: ", data
param.insert(i,data)
i+=1
#print "End of transmission"
s.close()
I created second while loop. I can listen continuously now, but I receive only one packet from the ESP (ESP send 9 packets). How to solve that issue?
If you want to continuously listen for connections and data from your remote end, you can achieve this using select()
A modified version of your code that uses select() is shown below. This will also handle the remote end closing the connection:
import sys
import socket
import select
TCP_IP = '127.0.0.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []
print 'Listening for client...'
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((TCP_IP,TCP_PORT))
server.listen(1)
rxset = [server]
txset = []
while 1:
rxfds, txfds, exfds = select.select(rxset, txset, rxset)
for sock in rxfds:
if sock is server:
conn, addr = server.accept()
conn.setblocking(0)
rxset.append(conn)
print 'Connection from address:', addr
else:
try:
data = sock.recv(BUFFER_SIZE)
if data == ";" :
print "Received all the data"
for x in param:
print x
param = []
rxset.remove(sock)
sock.close()
else:
print "received data: ", data
param.append(data)
except:
print "Connection closed by remote end"
param = []
rxset.remove(sock)
sock.close()
NB I've replaced your IP address with the loopback but you get the idea.
Hope this may be helpful.
I got problems with making a Python socket server receive commands from a Python socket client. The server and client can send text to each other but I can't make text from the client trigger an event on the server. Could any one help me? I'm using Python 3.4.
server.py
import socket
host = ''
port = 1010
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
print ("Connection from", addr)
while True:
databytes = conn.recv(1024)
if not databytes: break
data = databytes.decode('utf-8')
print("Recieved: "+(data))
response = input("Reply: ")
if data == "dodo":
print("hejhej")
if response == "exit":
break
conn.sendall(response.encode('utf-8'))
conn.close()
In server.py I tried to make the word "dodo" trigger print("hejhej").
client.py
import socket
host = '127.0.0.1'
port = 1010
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
print("Connected to "+(host)+" on port "+str(port))
initialMessage = input("Send: ")
s.sendall(initialMessage.encode('utf-8'))
while True:
data = s.recv(1024)
print("Recieved: "+(data.decode('utf-8')))
response = input("Reply: ")
if response == "exit":
break
s.sendall(response.encode('utf-8'))
s.close()
Everything here works fine but, maybe not the way you want it to. If you switch the order on a couple of the lines it will display your event string before you enter your server response.
import socket
host = ''
port = 1010
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
print ("Connection from", addr)
while True:
databytes = conn.recv(1024)
if not databytes: break
data = databytes.decode('utf-8')
print("Recieved: "+(data))
if data == "dodo": # moved to before the `input` call
print("hejhej")
response = input("Reply: ")
if response == "exit":
break
conn.sendall(response.encode('utf-8'))
conn.close()
I have been looking at some code for a small chat program that I found online. It was originally written for 2.7, but it seems to work with 3.2. The only problem is that I cannot send strings, only numbers:
The chat.py file source code:
from socket import *
HOST = ''
PORT = 8000
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print ('Connected by ' + str(addr))
i = True
while i is True:
data = conn.recv(1024)
print ("Received " + repr(data))
reply = str(input("Reply: "))
conn.send(reply)
conn.close()
And the client.py source file:
from socket import *
HOST = ''
PORT = 8000
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT)) # client-side, connects to a host
while True:
message = str(input("Your Message: "))
s.send(message)
print ("Awaiting reply...")
reply = s.recv(1024) # 1024 is max data that can be received
print ("Received " + repr(reply))
s.close()
When I run these using two separate terminals, they work, but do not send strings.
Thank you
When you work with sockets, the message you're passing around should probably be in bytes, b'bytes'. In Python 2.x, a str is actually what a bytes is in Python 3.x
So your message should be something like:
message = b'Message I want to pass'
Check here http://docs.python.org/3.3/library/stdtypes.html for more information.
According to http://docs.python.org/3/library/functions.html#input input returns a str, which means you'll have to encode message into bytes as such:
message = message.encode()
Do verify that this is the right approach to convert str to bytes by checking the type of message.
Your socket code is correct, it was just failing due to an unrelated error due to raw_input vs input. You probably intended to read a string from the shell instead of reading a string and trying to evaluate it as Python code which is what input does.
Try this instead:
chat.py
from socket import *
HOST = ''
PORT = 8000
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print ('Connected by ' + str(addr))
i = True
while i is True:
data = conn.recv(1024)
print ("Received " + repr(data))
reply = str(raw_input("Reply: "))
conn.send(reply)
conn.close()
client.py
from socket import *
HOST = ''
PORT = 8000
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT)) # client-side, connects to a host
while True:
message = str(raw_input("Your Message: "))
s.send(message)
print ("Awaiting reply...")
reply = s.recv(1024) # 1024 is max data that can be received
print ("Received " + repr(reply))
s.close()
Server
import socket
import sys
HOST = ''
PORT = 9000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'
conn, addr = s.accept()
print 'Connecting from: ' + addr[0] + ':' + str(addr[1])
while 1:
message=raw_input(">")
s.sendto(message, (addr[0], addr[1]))
print(s.recv(1024))
How do I make this send a message to the client?
I can make it reply to a string the client sends to the server, but in this case I want the server to send the first message...
Can anyone help me, The solutions on google don't seem to work properly and I'm not sure what I'm doing wrong.
Since this is the 1st Google Stack Overflow result for this, I'll post a complete, working example for both a client and a server. You can start either 1st. Verified working on Ubuntu 18.04 w/ Python 3.6.9
text_send_server.py:
# text_send_server.py
import socket
import select
import time
HOST = 'localhost'
PORT = 65439
ACK_TEXT = 'text_received'
def main():
# instantiate a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket instantiated')
# bind the socket
sock.bind((HOST, PORT))
print('socket binded')
# start the socket listening
sock.listen()
print('socket now listening')
# accept the socket response from the client, and get the connection object
conn, addr = sock.accept() # Note: execution waits here until the client calls sock.connect()
print('socket accepted, got connection object')
myCounter = 0
while True:
message = 'message ' + str(myCounter)
print('sending: ' + message)
sendTextViaSocket(message, conn)
myCounter += 1
time.sleep(1)
# end while
# end function
def sendTextViaSocket(message, sock):
# encode the text message
encodedMessage = bytes(message, 'utf-8')
# send the data via the socket to the server
sock.sendall(encodedMessage)
# receive acknowledgment from the server
encodedAckText = sock.recv(1024)
ackText = encodedAckText.decode('utf-8')
# log if acknowledgment was successful
if ackText == ACK_TEXT:
print('server acknowledged reception of text')
else:
print('error: server has sent back ' + ackText)
# end if
# end function
if __name__ == '__main__':
main()
text_receive_client.py
# text_receive_client.py
import socket
import select
import time
HOST = 'localhost'
PORT = 65439
ACK_TEXT = 'text_received'
def main():
# instantiate a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket instantiated')
# connect the socket
connectionSuccessful = False
while not connectionSuccessful:
try:
sock.connect((HOST, PORT)) # Note: if execution gets here before the server starts up, this line will cause an error, hence the try-except
print('socket connected')
connectionSuccessful = True
except:
pass
# end try
# end while
socks = [sock]
while True:
readySocks, _, _ = select.select(socks, [], [], 5)
for sock in readySocks:
message = receiveTextViaSocket(sock)
print('received: ' + str(message))
# end for
# end while
# end function
def receiveTextViaSocket(sock):
# get the text via the scoket
encodedMessage = sock.recv(1024)
# if we didn't get anything, log an error and bail
if not encodedMessage:
print('error: encodedMessage was received as None')
return None
# end if
# decode the received text message
message = encodedMessage.decode('utf-8')
# now time to send the acknowledgement
# encode the acknowledgement text
encodedAckText = bytes(ACK_TEXT, 'utf-8')
# send the encoded acknowledgement text
sock.sendall(encodedAckText)
return message
# end function
if __name__ == '__main__':
main()
Use the returned socket object from 'accept' for sending and receiving data from a connected client:
while 1:
message=raw_input(">")
conn.send(message)
print conn.recv(1024)
You just have to use send
Server.py
import socket
s = socket.socket()
port = 65432
s.bind(('0.0.0.0', port))
s.listen(5)
while True:
c, addr = s.accept()
msg = b"Hello World!"
c.send(msg)
Client.py
import socket
s = socket.socket()
port = 65432
s.connect(('127.0.0.1', port))