UDP client-server. Client not sending string to the server - python

I'm trying to split string if even or odd for example:
"Tea" will return two strings string1 = "Te" and string2 = "a" - odd
"Coffee" will return two strings string1 = "Cof" and string2 = "fee"
I've got a working algorithm that does that.
Then client needs to send this to the server. My question how to send this to the server. How server accepts these two strings?
I'm newbie to python. Please help.
Server side:
import socket
def Main():
host = '127.0.0.1'
port = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
print("Server Started")
while True:
data, addr = s.recvfrom(1024)
data = data.decode('utf-8')
print("Message From: " +str(addr))
print("From connected user: " + data)
data = data.upper()
print("Sending: " + data)
s.sendto(data.encode('utf-8'), addr)
s.close()
if __name__ == '__main__':
Main()
Client side:
import socket
def Main():
host = '127.0.0.1'
port = 5001
server = ('127.0.0.1', 5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
message = input('Please type a word ')
while message != '':
def splitWord(w):
split = -((-len(w))//2)
s1 = (w[:split])
s2 = (w[split:])
print(s1)
print(s2)
return
a = splitWord(message)
s.sendto(a.encode('utf-8'), server)
data, addr = s.recvfrom(1024)
data = data.decode('utf-8')
print("Received from server: " + data)
message = input('-> ')
s.close()
if __name__ == '__main__':
Main()

You might want to revisit your splitWord() function.
Inside splitWord() you create two substrings: s1 and s2, but don't do anything with them (other than printing). Your return is empty, and you don't modify the argument either.
A better way of to define this function is:
def splitWord(w):
return w[:len(w)/2], w[len(w)/2:]
Example:
a = "Coffee"
f,s = splitWord(a)
print f, s
-> Cof fee
Also there is no reason to define splitWord() inside the while loop.

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()

Didn't show desired output

Hello fellow programmer.
I followed this tutorial https://www.youtube.com/watch?v=QihjI84Z2tQ
Those server and client has successfully connected
but when i try build it did not show the desired output on the client-side terminal.
The server-side terminal does not react anything.
this is my code for server side:
import socket
import numpy as np
import encodings
HOST = '192.168.0.177' # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
def random_data(): # ANY DATA YOU WANT TO SEND WRITE YOUR SENSOR CODE HERE
x1 = np.random.randint(0, 55, None) # Dummy temperature
y1 = np.random.randint(0, 45, None) # Dummy humidigy
my_sensor = "{},{}".format(x1,y1)
return my_sensor # return data seperated by comma
def my_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print("Server Started waiting for client to connect ")
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024).decode('utf-8')
if str(data) == "Data":
print("Ok Sending data ")
my_data = random_data()
x_encoded_data = my_data.encode('utf-8')
conn.sendall(x_encoded_data)
elif str(data) == "Quit":
print("shutting down server ")
break
if not data:
break
else:
pass
if __name__ == '__main__':
while 1:
my_server()
and this is my client code:
import socket
import threading
import time
HOST = '192.168.0.177' # The server's hostname or IP address
PORT = 65432 # The port used by the server
def process_data_from_server(x):
x1, y1 = x.split(",")
return x1,y1
def my_client():
threading.Timer(11, my_client).start()
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
my = input("Data")
my_inp = my.encode('utf-8')
s.sendall(my_inp)
data = s.recv(1024).decode('utf-8')
x_temperature,y_humidity = process_data_from_server(data)
print("Temperature {}".format(x_temperature))
print("Humidity {}".format(y_humidity))
s.close()
time.sleep(5)
if __name__ == "__main__":
while 1:
my_client()
I have tried many solution by printing "Data" directly to the terminal.
can anyone help me?
Ok, I have found the problem. I am using Sublime Text 3 when running the client.py script When i post in the build it doesnt response nothing. So I change my IDE to PYCharm and then it worked. I don't know why. I hope that's helpful to other people that have this problem. Thank you very much.

Bad data being received

I am writing a client and server app in Python and I have a problem with received data. In the first "loop" I received good data but in the next "loop" I received bad data. What do I have to do? Maybe you have a better idea to send and receive data.
This is Client:
import socket
import pickle
import sys
host = socket.gethostname()
port = 2004
BUFFER_SIZE = 100000
print("What you want to do:\r1. Select from base\r2.Insert into base")
MESSAGE, MESSAGE1 = input("tcpClientA: Enter message/ Enter exit:").split(",")
tcpClientA = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpClientA.connect((host, port))
while MESSAGE != 'exit':
tcpClientA.send(MESSAGE.encode())
tcpClientA.send(MESSAGE1.encode())
lista=pickle.loads(tcpClientA.recv(BUFFER_SIZE).strip())
print(lista)
print("Variables 1 and 2 are: ", MESSAGE, MESSAGE1)
MESSAGE, MESSAGE1 = input("tcpClientA: Enter message to continue/ Enter exit:").split(",")
tcpClientA.close()
This is Server:
import socket
from threading import Thread
import pyodbc
import pickle
# Multithreaded Python server : TCP Server Socket Thread Pool
class ClientThread(Thread):
def __init__(self,ip,port):
Thread.__init__(self)
self.ip = ip
self.port = port
print ("[+] New server socket thread started for " + ip + ":" + str(port) )
def run(self):
while True :
connsql = pyodbc.connect('DRIVER={SQL Server};SERVER=I7-KOMPUTER\SQLEXPRESS;DATABASE=test')
cursor = connsql.cursor()
data = conn.recv(2048)
#datasplitx, datasplity = data.decode().split(",", 1)
try:
xy = []
xy = data.decode().split(" ")
print("dat: ",data.decode())
print("After del:",xy)
x=str(xy[0])
#y=str(xy[1])
#x, y = [str(x) for x in data.decode().split()]
#y=str(datasplit[1])
#x = str(datasplit[0])
#y = str(datasplit[1])
except ValueError:
print("List does not contain value")
print ("Server received data:", xy)
if x == 'exit':
break
if x == '1':
#if data.decode() == '1':
cursor.execute("select rtrim(name) from client")
rows = cursor.fetchall()
zap=pickle.dumps(rows)
conn.send(zap)
print(pickle.loads(zap))
if x == '2':
#if data.decode() == '2':
cursor.execute("insert into dbo.klient values('"+y+"')")
connsql.commit()
zro=pickle.dumps("Done.")
conn.send(zro)
del xy[:]
print ("cleared list: xy",xy)
# Multithreaded Python server : TCP Server Socket Program Stub
TCP_IP = '0.0.0.0'
TCP_PORT = 2004
BUFFER_SIZE = 1024 # Usually 1024, but we need quick response
tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpServer.bind((TCP_IP, TCP_PORT))
threads = []
while True:
tcpServer.listen(4)
print ("Multithreaded Python server : Waiting for connections from TCP clients...\r" )
(conn, (ip,port)) = tcpServer.accept()
newthread = ClientThread(ip,port)
newthread.start()
threads.append(newthread)
print("Client IP: " +str(ip))
for t in threads:
t.join()

Cannot Get Strings Across in a Socket Program

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()

Receive more than one message on more than one port Echo Server python

I am writing a echo server and client in Python, that implements a simple number guessing game. I know how to multiplex using select, that's fine. The other server I wrote achieves this. But now I am writing a new server (which is fairly similar), however it accepts connections from two ports rather than one, one port for player client, and one for admin which I will use eventually for the who command, returning all connected players.
My problem is, that after sending the initial greetings message, the clients receive feedback from the server on the first send, recv. But after that I cannot send any more messages to server (nothing gets sent from the clients), I have been searching and playing around for hours, to no avail. Any help would be appreciated. Thanks!
# MULTIPLEX SERVER
import socket, select, time, random, ssl, sys, os
# VARS
EXP = 1
HOST = '127.0.0.1'
PORT_P = 4000
PORT_A = 4001
BUFFSZ = 1024
BKLOG = 5
GREETS = 'Greetings'
INPUTS = []
OUTPUTS = []
CLIENT_ADDRS = {}
CLIENT_ANS = {}
CLIENTS = ""
_adm_rtnMSG = 'Admin_Greetings'
# Function to determine how far the player is
# from the chosen random number
def Within(value, target):
diff = abs(target - value)
if diff > 3:
return 'Not even close, youth!'
else:
return 'Ooh, not to far: ' + str(diff) + ' away, keep trying...'
# END_FUNCTION
print('Server up and running...\n')
try:
for p in PORT_P, PORT_A:
INPUTS.append(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
INPUTS[-1].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
INPUTS[-1].bind((HOST, p))
INPUTS[-1].listen(BKLOG)
except socket.error(value, message):
if INPUTS[-1]:
INPUTS[-1].close()
INPUTS = INPUTS[:-1]
print('Failure to open socket: ' + message)
sys.exit(1)
while True:
READ_IO, WRITE_IO, ERROR = select.select(INPUTS, OUTPUTS, INPUTS)
for r in READ_IO:
for p in INPUTS:
if r is p:
(acpt_sock, addr) = p.accept()
print('Connection established with ', acpt_sock.getsockname())
CLIENT_ADDRS[acpt_sock] = addr
CLIENT_ANS[acpt_sock] = random.randrange(1, 20)
else:
data = acpt_sock.recv(BUFFSZ).decode()
acpt_sock.setblocking(0)
if data:
if 'Hello' in data:
print(CLIENT_ADDRS[acpt_sock], ' random number is: ', CLIENT_ANS[acpt_sock])
acpt_sock.send(b'Greetings\nGuess a random number between 1 & 20')
# drop elif here for admin cmd
elif 'Hi' in data:
acpt_sock.send(_adm_rtnMSG.encode())
else:
if int(data) == CLIENT_ANS[acpt_sock]:
acpt_sock.send(b'That was correct, Well done!')
else:
acpt_sock.send(str(Within(int(data), CLIENT_ANS[acpt_sock])).encode())
else:
print('Closing Connection # ', addr)
INPUTS.remove(acpt_sock)
acpt_sock.close()
del CLIENT_ADDRS[acpt_sock]
# PLAYER CLIENT
import socket
import re
# INIT VARS
HOST = '127.0.0.1'
PORT = 4000
INITSTR = 'Hello'
BUFF = 1024
# Set up socket
sender = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sender.connect((HOST, PORT))
sender.send(bytes((INITSTR), "ascii"))
print("Kirby Prompt FTW!\nConnected to Server via", HOST, "::", PORT, '\n')
rtnMSG = sender.recv(BUFF).decode()
print(rtnMSG)
# Simple loop to keep client alive
# to send and receive data from the server
while 'correct' not in rtnMSG:
_guess = input("(>',')> ")
sender.send(bytes((_guess), "ascii"))
rtnMSG = sender.recv(BUFF).decode()
print(rtnMSG)
sender.close()
# ADMIN CLIENT
import socket
import re
import ssl
# INIT VARS
HOST = '127.0.0.1'
PORT = 4001
INITSTR = 'Hi'
BUFF = 1024
# Set up socket
adm_sender = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
adm_sender.connect((HOST, PORT))
adm_sender.send(bytes((INITSTR), "ascii"))
print("Connected to Server as Admin via", HOST, "::", PORT, '\n')
rtnMSG = adm_sender.recv(BUFF).decode()
print(rtnMSG)
while True:
cmd = input('$ ')
adm_sender.send(bytes((cmd), "ascii"))
rtnMSG = adm_sender.recv(BUFF).decode()
print(rtnMSG)
adm_sender.close()

Categories

Resources