socket recv() is not returning in Python - python

I was writing an echo server but recv() does not return while the sender process is alive. If I use one recv() call instead of my recvall() function, it is returning and working. Please let me know what is wrong with recvall() function..
Server:
import socket
def recvall(skt):
msg_total = b""
while True:
msg = skt.recv(1024)
if not msg: break
msg_total += msg
return msg_total
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost",3333))
s.listen()
conn,addr = s.accept()
# data = conn.recv(1024) <= this recv() is not blocking
data = recvall(conn)
conn.sendall(data)
main()
Client:
import socket
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost",3333))
msg = ("a" * 10).encode()
s.sendall(msg)
rsp = s.recv(1024)
main()

Related

How to break while loop when a new message arrives?

I have used Python socket in ESP as a server and Laptop as a client. I customized the socket codes from this site. When I send the loop as the client input, I enter a loop on the server. I don't know how the while loop is broken when I send a word other than loop, For example "Hello".
server.py:
import socket
host = ''
port = 5560
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((host, port))
except socket.error as msg:
print(msg)
print("Socket bind comlete.")
return s
def setupConnection():
s.listen(1)
conn, address = s.accept()
print("Connected to: " + address[0] + ":" + str(address[1]))
return conn
def Hello_():
print('Hello')
def Loop_():
while True:
print('yes')
def dataTransfer(conn):
while True:
data = conn.recv(1024)
data = data.decode('utf-8')
dataMessage = data.split(' ', 1)
command = dataMessage[0]
if command == 'loop':
Loop_()
if command == 'Hello':
Hello_()
else:
print("X")
conn.close()
s = setupServer()
while True:
try:
conn = setupConnection()
dataTransfer(conn)
except:
break
client.py
import socket
host = '192.168.56.1'
port = 5560
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
command = input("Enter your command: ")
s.send(str.encode(command))
s.close()
I know your time is valuable and I appreciate your attention for spending time for help me.
If you want the Loop_() method to return when more data is received on the socket, you can modify the method so that it calls select() to poll the socket to see if more data has arrived, as shown below. (Note that I've added a conn argument to the Loop_() method so I can pass in the socket to check it)
import select
[...]
def Loop_(conn):
while True:
print('yes')
inReady, outReady, exReady = select.select([conn], [], [], 0.0)
if (conn in inReady):
print('more data has arrived at the TCP socket, returning from Loop_()')
break
def dataTransfer(conn):
while True:
data = conn.recv(1024)
data = data.decode('utf-8')
dataMessage = data.split(' ', 1)
command = dataMessage[0]
if command == 'loop':
Loop_(conn)
if command == 'Hello':
Hello_()
else:
print("X")
conn.close()

Network server only sending data to client once instead of looping

I'm sorry if this is a really dumb question, I'm sure someone could probably find the answer in a minute, I've just recently been getting into Python sockets.
I want my server to continually send a stream of data to my client, but for some reason, after receiving the first piece of data my client just does not receive/print out any more data.
My simplified server.py:
while True:
#do some stuff with dfwebsites here
senddata = True
#time.sleep(1)
#Starting the sending data part
HEADERSIZE = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(),1236))
s.listen(5) #queue of five
while senddata==True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established!")
d = pd.DataFrame(dfwebsites)
msg = pickle.dumps(d)
#header to specify length
#msg = "Welcome to the server!"
msg = bytes(f'{len(msg):<{HEADERSIZE}}','utf-8')+msg
clientsocket.send(msg) #type of bytes is utf-8
#clientsocket.close()
senddata = False
My client.py:
import socket
import pickle
import time
HEADERSIZE = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1236))
while True:
full_msg = b''
new_msg = True
while True:
msg = s.recv(1024)
if new_msg:
print("new msg len:",msg[:HEADERSIZE])
msglen = int(msg[:HEADERSIZE])
new_msg = False
print(f"full message length: {msglen}")
full_msg += msg
print(len(full_msg))
if len(full_msg)-HEADERSIZE == msglen:
print("full msg recvd")
print(full_msg[HEADERSIZE:])
print(pickle.loads(full_msg[HEADERSIZE:]))
new_msg = True
full_msg = b""
Why can it not receive more than one peice of data?
Thank you so much for your help! I would really love even a comment telling me how to improve my qeustion!
To send more than one message to each client, you need a loop after the accept() has happened.
#!/usr/bin/env python
import socket
import pickle
import pandas as pd
HEADERSIZE = 10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(),1236))
s.listen(5) # only one client at a time, but let up to five wait in line
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established!")
while senddata:
# FIXME: refresh dfwebsites every time through this loop?
d = pd.DataFrame(dfwebsites)
msg = pickle.dumps(d)
msg = bytes(f'{len(msg):<{HEADERSIZE}}','utf-8')+msg
try:
clientsocket.send(msg) #type of bytes is utf-8
except socket.error as exc:
print(f"Ending connection from client {address} due to {exc}")
# FIXME: Do the below only when you want to disconnect a client
#senddata = False
clientsocket.close()

Python Socket Call server.py and client.py in main.py

My question is that how to call server and client sequentially in main method ?
Problem is that python debugger waiting and be suck in line that calling the server(blocking the calling client line).
I tried threading but not work . Thanks for your attention.
IMPORTANT: Below codes using Python2
Main python file:
import xClient
import xServer
import threading
tempServer=xServer
tempClient=xClient
thrMain = threading.Thread(target=tempServer.innerClient.Main())
thrMain.start()
thrMain.join()
tempClient.innerClient.Main()
xClient.py : # STANDARD Client code and works correctly
import socket
import time
class innerClient:
def Main():
time.sleep(2)
host = '127.0.0.1'
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
message = "test message"
while True:
s.send(message.encode('ascii'))
data = s.recv(1024)
print('Received from the server :', str(data.decode('ascii')))
ans = raw_input('Continue(y/n) :')
if ans == 'y':
continue
else:
break
s.close()
xServer.py : # STANDARD Server code and works correctly
import socket
import threading
class innerServer:
print_lock = threading.Lock()
# thread fuction
def threaded(c):
while True:
data = c.recv(1024)
if not data:
print('See you later')
print_lock.release()
break
data = data[::-1]
c.send(data)
c.close()
def Main():
host = ""
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("socket binded to post", port)
s.listen(5)
print("socket is listening")
while True:
c, addr = s.accept()
print_lock.acquire()
print('Connected to :', addr[0], ':', addr[1])
thr = threading.Thread(target=threaded, args=(c,))
thr.start()
thr.join()
s.close()
TCP Socket Diagram

Python, I want to make Multiple Connection Chatting Program

I coded chatting program with socket module.
(Python)
and I saw perfect send and get data.
But I found a problem.
This is my Server.py
import socket
import threading
HOST = '127.0.0.1'
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print(addr)
def sendmsg():
while True:
data = input()
data = data.encode("utf-8")
conn.send(data)
conn.close()
def getmsg():
while True:
data = conn.recv(1024)
if data is None:
break
else:
data = data.decode("utf-8", "ignore")
print(data)
conn.close()
threading._start_new_thread(sendmsg, ())
threading._start_new_thread(getmsg, ())
while True:
pass
Just on Client can connect with server.
I want to make multiple connection.
So I changed value of s.listen(1) to s.listen(2)
but It doesn't work.
Help me TT
This is client.py
import socket
import threading
HOST = "127.0.0.1"
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
def sendMsg():
while True:
data = input()
s.sendall(str.encode(data))
s.close()
def getMsg():
while True:
data = s.recv(1024)
data = data.decode("utf-8")
print(data)
s.close()
threading._start_new_thread(sendMsg, ())
threading._start_new_thread(getMsg, ())
while True:
pass
Thank you.

python socket : server must send a message before recv

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

Categories

Resources