Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I created a socket server to read the commands from a socket client. In client side, I send ABC and then DEF, in server side, each time I received ABC or DEF from client, the server will send back to client OK.
Server
import socket
import sys
host = socket.gethostname()
port = 12345
server_tcp = socket.socket()
server_tcp.bind((host, port))
server_tcp.listen(5)
while True:
c, addr = server_tcp.accept()
data = c.recv(1024)
print ('data received: %s') % data
if 'ABC' == data:
print ('sending back ok to the client')
texte = 'OK';
n=c.send(texte)
else:
print ('I did not get the right command ABC')
break
data = c.recv(1024)
print ('data received: %s') % data
if 'DEF' == data:
print ('sending back ok to the client')
texte = 'OK';
n=c.send(texte)
else:
print ('I did not get the right command DEF')
break
c.close()
Socket client:
import socket
import sys
host = socket.gethostname()
port = 12345
client_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
rc = client_tcp.connect((host, port))
except:
print('Server not found')
texte = 'ABC';
n=client_tcp.send(texte)
data=client_tcp.recv(1024);
print (data)
if 'OK' == data:
print('good')
else:
print('bad')
texte = 'DEF';
n=client_tcp.send(texte)
data=client_tcp.recv(1024);
print (data)
if 'OK' == data:
print('good')
else:
print('bad')
client_tcp.close() # Close the socket when done
When I set the command in client with order ABC - DEF I receive OK - OK in server. But with DEF - ABC, I just only received only one OK.
Best regards
I made some changes to your code to test it. The problem is that you are not sending the response that the client is waiting for. It happens when the wrong command arrives.
if your client is waiting for information YOUR SERVER MUST SENDS INFORMATION!... and it's the same for the other side (Server).
In the end, your problem is an issue of protocol. You must design what kind of message will be changed between different parts and be sure that those messages are sent and received
Server:
import socket
import sys
host = socket.gethostname()
port = 9966
server_tcp = socket.socket()
server_tcp.bind((host, port))
server_tcp.listen(5)
n = 0
while n < 2:
c, addr = server_tcp.accept()
inData = c.recv(1024)
data = inData.decode()
texte = '';
print ('data received: {0}'.format(data))
if 'ABC' == data:
print ('sending back ok to the client')
texte = 'OK';
else:
print ('I did not get the right command ABC')
texte = 'FAIL';
#break
print("Respose: {0}".format(texte))
#ALWASY SEND THE RESPONSE IF YOUR CLIENT WAITS FOR IT
c.sendall(texte.encode(encoding = 'UTF-8'))
inData = c.recv(1024)
data = inData.decode()
print ('data received: {0}'.format(data))
if 'DEF' == data:
print ('sending back ok to the client')
texte = 'OK';
#n=c.send(texte.encode(encoding = 'UTF-8'))
else:
print ('I did not get the right command DEF')
texte = 'FAIL';
#break
print("Respose: {0}".format(texte))
#ALWASY SEND THE RESPONSE IF YOUR CLIENT WAITS FOR IT
c.sendall(texte.encode(encoding = 'UTF-8'))
print ('Closing Socket Client')
c.close()
n += 1
Client:
import socket
import sys
host = socket.gethostname()
port = 9966
client_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
rc = client_tcp.connect((host, port))
except:
print('Server not found')
#texte = "ABC"
texte = "DEF"
n=client_tcp.send(texte.encode(encoding = 'UTF-8'))
inData=client_tcp.recv(1024)
data = inData.decode()
print ("[" + data + "]")
if 'OK' == data:
print('good')
else:
print('bad')
#texte = "DEF"
texte = "ABC"
n=client_tcp.send(texte.encode(encoding = 'UTF-8'))
inData=client_tcp.recv(1024)
data = inData.decode()
print ("[" + data + "]")
if 'OK' == data:
print('good')
else:
print('bad')
client_tcp.close()
Client's output Order ABC DEF:
[OK]
good
[OK]
good
Client's output Order DEF ABC:
[FAIL]
bad
[FAIL]
bad
Related
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()
my raspberry pi is the server and Im trying to send continuous message from rpi to android while recieving a command from client (android app),i really dont know if this is possible and how to do it is out of my reach and it is not a feedback message here is my code hope you will help me thank you.
import apptopi
from socket import *
from time import ctime
from nanpy import (ArduinoApi, SerialManager)
apptopi.setup()
connection = SerialManager()
a = ArduinoApi(connection = connection)
ctrCmd = ['Up','Down','Left','Right','Stop','Connect']
add = 0
add += 1
a = str(add) //**this is a sample that i want to send continously
HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(0)
tcpSerSock.send(str.encode(a)) <== i really don't know how to send
continuously
while True:
print 'Waiting for connection'
tcpCliSock,addr = tcpSerSock.accept()
print '...connected from :', addr
try:
while True:
data = ''
data = tcpCliSock.recv(BUFSIZE)
if not data:
break
if data == ctrCmd[0]:
apptopi.forw()
print 'forward'
if data == ctrCmd[1]:
apptopi.back()
print 'backward'
if data == ctrCmd[2]:
apptopi.left()
print 'leftturn'
if data == ctrCmd[3]:
apptopi.right()
print 'rightturn'
if data == ctrCmd[4]:
apptopi.stp()
print 'stop'
except KeyboardInterrupt:
apptopi.close()
GPIO.cleanup()
tcpSerSock.close();
OK one approach is to use the select() function for this. There is information in the documentation about its operation.
As an example I've made a modified version of your program (see below). I don't have a raspberry pi, so that part of the code is commented out, but you can replace it as needed.
The example uses the timeout feature of select() to send "continuous" messages to clients whilst also monitoring them for incoming messages. You can adjust the message contents and timeout to whatever works for you. NB you may also need to respond to client messages, as this code only sends data to clients after a timeout. Make whatever changes you need.
import sys
import socket
import select
ctrCmd = ['Up','Down','Left','Right','Stop','Connect']
HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)
tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(1)
print 'Waiting for connection'
sendInterval = 1.0 # interval(sec) for sending messages to connected clients
rxset = [tcpSerSock]
txset = []
while 1:
rxfds, txfds, exfds = select.select(rxset, txset, rxset, sendInterval)
if rxfds:
for sock in rxfds:
if sock is tcpSerSock:
# a client is connecting
tcpCliSock, addr = tcpSerSock.accept()
tcpCliSock.setblocking(0)
rxset.append(tcpCliSock)
print '...connected from :', addr
else:
# a client socket has data or has closed the connection
try:
data = sock.recv(BUFSIZE)
if not data:
print "...connection closed by remote end"
rxset.remove(sock)
sock.close()
else:
if data == ctrCmd[0]:
#apptopi.forw()
print 'forward'
if data == ctrCmd[1]:
#apptopi.back()
print 'backward'
if data == ctrCmd[2]:
#apptopi.left()
print 'leftturn'
if data == ctrCmd[3]:
#apptopi.right()
print 'rightturn'
if data == ctrCmd[4]:
#apptopi.stp()
print 'stop'
except:
print "...connection closed by remote end"
rxset.remove(sock)
sock.close()
else:
# timeout - send data to any active client
for sock in rxset:
if sock is not tcpSerSock:
sock.send("Hello!\n")
The simple client program I used to test this is here:
import sys
import socket
import time
ctrCmd = ['Up','Down','Left','Right','Stop','Connect']
HOST = '127.0.0.1'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)
tcpCliSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpCliSock.connect(ADDR)
time.sleep(1)
for i in range(len(ctrCmd)):
tcpCliSock.send(ctrCmd[i])
time.sleep(1)
data = tcpCliSock.recv(BUFSIZE)
print data
tcpCliSock.close()
Hope this helps, best of luck.
The problem I'm having is to get a file from the server. Lets say I want to
"get ./testing.pdf" which sends the pdf from the server to the client. It sends but it is always missing bytes. Is there any problems with how I am sending the data. If so how can I fix it? I left out the code for my other functionalities since they are not used for this function.
server.py
import socket, os, subprocess # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
#host = ''
port = 5000 # Reserve a port for your service.
bufsize = 4096
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
while True:
userInput = c.recv(1024)
.... CODE ABOUT OTHER FUNCTIONALITY
elif userInput.split(" ")[0] == "get":
print "inputed get"
somefile = userInput.split(" ")[1]
size = os.stat(somefile).st_size
print size
c.send(str(size))
bytes = open(somefile).read()
c.send(bytes)
print c.recv(1024)
c.close()
client.py
import socket, os # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
#host = '192.168.0.18'
port = 5000 # Reserve a port for your service.
bufsize = 1
s.connect((host, port))
print s.recv(1024)
print "Welcome to the server :)"
while 1 < 2:
userInput = raw_input()
.... CODE ABOUT OTHER FUNCTIONALITY
elif userInput.split(" ")[0] == "get":
print "inputed get"
s.send(userInput)
fName = os.path.basename(userInput.split(" ")[1])
myfile = open(fName, 'w')
size = s.recv(1024)
size = int(size)
data = ""
while True:
data += s.recv(bufsize)
size -= bufsize
if size < 0: break
print 'writing file .... %d' % size
myfile = open('Testing.pdf', 'w')
myfile.write(data)
myfile.close()
s.send('success')
s.close
I a server and client for a socket connection in Python,
client:
import socket
import sys
from sys import stdin
serv = 'ip goes here'
port = 8888
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((serv, port))
def prompt():
sys.stdout.write('<You> ')
sys.stdout.flush()
def send(x):
sock.sendall(x)
rec = 0
ex = len(x)
while rec < ex:
data = sock.recv(16)
rec += len(data)
while 1:
if sock:
data = sock.recv(16)
if len(data) == 0:
pass
print '<Server> %s' % data
prompt()
msg = stdin.readline()
sock.sendall(msg)
The way I have it now, if you say something on one client, it will send "alphabet" to both clients but the other clients will not receive that until they send a new message as it is waiting for stdin.readline() to occur. I was wondering how to make it so the clients will always receive data from the server, and will see it without having to have stdin.readline() happen first.
Thanks
Achieved what I wanted by using threads as suggested by CrazyCasta
def receiving():
while 1:
if sock:
data = sock.recv(16)
if len(data) == 0:
pass
print '<Server> %s' % data
def sending():
while 1:
msg = stdin.readline()
sock.sendall(msg)
t1 = Thread(target=receiving)
t2 = Thread(target=sending)
t1.start()
t2.start()
I'm trying to send and receive files through a TCP socket. When user types put abc.txt, abc.txt should be copied to the server.
When user types get def.txt, def.txt should be downloaded to the user computer. (Actually I have to implement 2 more methods - ls to list all files in the client directory and lls to list all files in the server, but I haven't done it yet.)
Here's the code
Server
import socket
import sys
HOST = 'localhost'
PORT = 3820
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind((HOST, PORT))
socket.listen(1)
while (1):
conn, addr = socket.accept()
print 'New client connected ..'
reqCommand = conn.recv(1024)
print 'Client> %s' %(reqCommand)
if (reqCommand == 'quit'):
break
#elif (reqCommand == lls):
#list file in server directory
else:
string = reqCommand.split(' ', 1) #in case of 'put' and 'get' method
reqFile = string[1]
if (string[0] == 'put'):
with open(reqFile, 'wb') as file_to_write:
while True:
data = conn.recv(1024)
if not data:
break
file_to_write.write(data)
file_to_write.close()
break
print 'Receive Successful'
elif (string[0] == 'get'):
with open(reqFile, 'rb') as file_to_send:
for data in file_to_send:
conn.sendall(data)
print 'Send Successful'
conn.close()
socket.close()
Client
import socket
import sys
HOST = 'localhost' #server name goes in here
PORT = 3820
def put(commandName):
socket.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'rb') as file_to_send:
for data in file_to_send:
socket.sendall(data)
print 'PUT Successful'
return
def get(commandName):
socket.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'wb') as file_to_write:
while True:
data = socket.recv(1024)
#print data
if not data:
break
print data
file_to_write.write(data)
file_to_write.close()
break
print 'GET Successful'
return
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((HOST,PORT))
msg = raw_input('Enter your name: ')
while(1):
print 'Instruction'
print '"put [filename]" to send the file the server '
print '"get [filename]" to download the file from the server '
print '"ls" to list all files in this directory'
print '"lls" to list all files in the server'
print '"quit" to exit'
sys.stdout.write ('%s> ' %msg)
inputCommand = sys.stdin.readline().strip()
if (inputCommand == 'quit'):
socket.send('quit')
break
# elif (inputCommand == 'ls')
# elif (inputCommand == 'lls')
else:
string = inputCommand.split(' ', 1)
if (string[0] == 'put'):
put(inputCommand)
elif (string[0] == 'get'):
get(inputCommand)
socket.close()
There are several problems that I couldn't fix.
The program run correctly only on the first time (both 'put' and
'get' method). After that, All commands from the client can't be
sent to the server.
The 'get' method doesn't work for an image/photo file.
First problem is occurring because after handling one command, server is closing the connection.
conn.close()
Second problem is occurring because you are not reading all the data from the socket in client. At the end of while loop you have a "break" statement, due to which client is closing the socket just after reading 1024 bytes. And when server tries to send data on this close socket, its results in error on the server side.
while True:
data = socket1.recv(1024)
# print data
if not data:
break
# print data
file_to_write.write(data)
file_to_write.close()
break
There are two ways to fix this first issue.
Change the client so that for each command it creates a new connection & sends command to the server.
Change the server to handle multiple commands over the same connection.
Following code is the changed client to demonstrate the first way to fix the first issue. It also fixes the second issue.
import socket
import sys
HOST = 'localhost' # server name goes in here
PORT = 3820
def put(commandName):
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.connect((HOST, PORT))
socket1.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'rb') as file_to_send:
for data in file_to_send:
socket1.sendall(data)
print 'PUT Successful'
socket1.close()
return
def get(commandName):
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.connect((HOST, PORT))
socket1.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'wb') as file_to_write:
while True:
data = socket1.recv(1024)
# print data
if not data:
break
# print data
file_to_write.write(data)
file_to_write.close()
print 'GET Successful'
socket1.close()
return
msg = raw_input('Enter your name: ')
while(1):
print 'Instruction'
print '"put [filename]" to send the file the server '
print '"get [filename]" to download the file from the server '
print '"ls" to list all files in this directory'
print '"lls" to list all files in the server'
print '"quit" to exit'
sys.stdout.write('%s> ' % msg)
inputCommand = sys.stdin.readline().strip()
if (inputCommand == 'quit'):
socket.send('quit')
break
# elif (inputCommand == 'ls')
# elif (inputCommand == 'lls')
else:
string = inputCommand.split(' ', 1)
if (string[0] == 'put'):
put(inputCommand)
elif (string[0] == 'get'):
get(inputCommand)