Issue with Python sockets between client and server - python

I am getting a headache from trying to figure out where the problem is. I have a basic client and a server, the client sends a request and the server replies with an answer, the problem is, that the server does not send what is expected from him.
I would really appreciate anyone that can help me, thank you very much.
Here is the code:
client code:
def main():
import socket
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
my_socket.connect(('127.0.0.1',8000))
info = input(r"Enter what you want to send to the server: ")
while info != "exit":
my_socket.send(info.encode('ascii'))
if info != "EXIT":
data_from_server = my_socket.recv(2).decode('ascii')
data_from_server = my_socket.recv(int(data_from_server))
print(data_from_server.decode('ascii'))
info = input("Enter what you want to send to the server: ")
else:
info = "exit"
my_socket.close()
if __name__ == '__main__':
main()
Here is the server code:
import socket
import sys
import time
from random import randrange
SERVER_NAME = "010101"
def number_of_elements(str):
num = 0
for e in str:
num += 1
return num
def main():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0',8000))
while True:
server_socket.listen(1)
client_socket, client_adresss = server_socket.accept()
client_request = client_socket.recv(4)
while client_request != b'EXIT':
if client_request == b'TIME':
num_of_chars = number_of_elements(time.ctime())
client_socket.send(str(num_of_chars).encode('ascii'))
client_socket.send(time.ctime().encode('ascii'))
elif client_request == b'NAME':
num_of_chars = number_of_elements(SERVER_NAME)
client_socket.send(str(num_of_chars).encode('ascii'))
client_socket.send(SERVER_NAME.encode('ascii'))
elif client_request == b'RAND':
num = 2
client_socket.send(str(num).encode('ascii'))
random_num = randrange(11)
client_socket.send(str(random_num).encode('ascii'))
else:
s = str(len("Incorrect Command"))
client_socket.send(s.encode('ascii'))
client_socket.send(b"Incorrect Command")
try:
client_request = client_socket.recv(4)
except:
client_request = b"EXIT"
client_socket.close()
server_socket.close()
if __name__ == '__main__':
main()
Here's an example

This call:
client_request = client_socket.recv(4)
Means you are asking for 4 bytes. But the socket library can, and will deliver less than that based on the behavior of TCP. And your code is not checking the number of bytes actually received.
Code your server as if it was only going to receive 1 byte at a time. And/or be prepared to invoke recv multiple times and to accumulate the number of bytes into a sequential buffer until the expected number has been received.

Related

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.

TCP Multithread Python

I am new to Python and also Thread and I'm trying to make a TCP server in python.
The client connect good to the server but can only put 1 command, then it crash, here is the code :
serverSocket = socket(AF_INET, SOCK_STREAM)
def Main():
serverPort = 7722
print("The server is ready to receive on port", serverPort)
serverSocket.bind(('', serverPort))
serverSocket.listen(1)
def start_socket(connectionSocket):
while True:
print('Connection requested from', clientAddress)
client_code_number = connectionSocket.recv(2048)
server_code_number = client_code_number.decode()
if (server_code_number == "1"):
print("Command 1\n\n")
message = connectionSocket.recv(2048)
modifiedMessage = message.decode().upper()
connectionSocket.send(modifiedMessage.encode())
connectionSocket.close()
if __name__ == '__main__':
Main()
while True:
(connectionSocket, clientAddress) = serverSocket.accept()
os.system('cls')
print('connexion from: ' + str(clientAddress))
_thread.start_new_thread(start_socket, (connectionSocket,))
serverSocket.close()
Here is the client :
def start_socket():
init_text()
choice_number = input('Input option: ')
#GET THE USER NUMBER
clientSocket.send(choice_number.encode())
while True:
if choice_number == "1":
sentence_caps = input('Input sentence: ')
clientSocket.send(sentence_caps.encode())
modifiedMessage = clientSocket.recv(2048)
print('\nReply from server:', modifiedMessage.decode())
start_socket()
else:
start_socket()
And here is my error :
File "BasicTCPServer.py", line 33, in start_socket
client_code_number = connectionSocket.recv(2048)
OSError: [Errno 9] Bad file descriptor
The root cause is that the socket is being closed.
def start_socket(connectionSocket):
while True:
print('Connection requested from', clientAddress) # <-- where does client address come from
client_code_number = connectionSocket.recv(2048) # <-- this works the first time round
server_code_number = client_code_number.decode()
if (server_code_number == "1"):
...
connectionSocket.close() # <-- this closes the socket
Your code is complaining about the second time through the loop. connectionSocket has been closed, so it is a bad file descriptor.

Chat Program Threaded

I am trying to build a small chat server/client using python. So far I think I managed to set it up but I am running into issues. I wanted to set the program up to be multithreaded to keep the server listening for connections, and to also continue to listen for data and then have the main program loop stay in the client send. Here is my code, and I am running into an issue when starting the listen function, it tells me the argument must be an iterable not socket.
import socket
import platform
import os
import threading
'''Define Globals'''
HOST = ""
PORT = 25000
ADDR = (HOST, PORT)
BUF = 1024
def client_send():
server_ip = input("[+] Server's IP to connect to: ")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((server_ip, 25000))
data_thread = threading.Thread(target=client_listen, args=(client_socket))
data_thread.start()
while True:
data = input("[%s] => " % os.getlogin())
client.send(str.encode("[%s] => " + data % os.getlogin()))
def client_listen(client):
while True:
print(client.recv(BUF))
def server_loop():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
server.listen(10)
print("[+] Server started on %s" %platform.node())
print("[+] Awaitiing connection from client..")
while True:
client_socket, client_addr = server.accept()
print("[+] New Connection from %s" %client_addr[0])
def main():
server_thread = threading.Thread(target=server_loop)
while True:
try:
print("Select Operating Mode")
print("---------------------")
print("1. Server Mode")
print("2. Client Mode")
mode = int(input("Enter mode of operation: "))
print("")
print("")
if mode in [1,2]:
break
else:
raise ValueError
except ValueError:
print("Enter either (1) for Server or (2) for Client")
if mode == 1:
server_thread.start()
elif mode == 2:
client_send()
main()
You need to make the arguments a tuple.
You should supply an extra comma after the argument list as in:
data_thread = threading.Thread(target=client_listen, args=(client_socket,))
The difference can be seen when you look into the types of both:
>>> type((client_socket))
<class 'socket._socketobject'>
>>> type((client_socket,))
<type 'tuple'>

python threading, admin and client

I have been doing some development on this project. achieving multiple connections for the client to the sever. However i am now trying to implement the admin connections through a different port number. Which will not conflict the operation to the client. I changed it so that it calls the function which then calls the operations for which the client or admin which then plays the game or admin controls. how do i call the port number to that function so it runs that code? which calls the game or admin controls? (new to coding) however i feel i need to call them at the bottom of the script....
`# Server
import socket
import math
import random
import re
import threading
#TCP_IP = '127.0.0.1'
#TCP_PORT = 4001
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((TCP_IP, TCP_PORT))
#s.listen(5)
#print("Waiting...")
#connection check
def handle_ClientPort(port): # porting for client through threading
s.bind(("127.0.0.1",port))
s.listen(5)
while True:
(c,a) = s.accept()
t = threading.Thread(target = handle_client, args = (c,a))
t.start()
def handle_AdminPort(port): #proting for adminm connection through threading
s.bind(("127.0.0.1",port))
s.listen(5)
while True:
(c,a) = s.accept()
t = threading.Thread(target = Admin_client, args = (c,a))
t.start()
def handle_Admin(c,a): #function for admin controls
while True:
text = c.recv(80).decode()
if text == 'Who':
c.send("who has workd".encode())
elif text == 'Hello':
c.send('Admin-Greetings'.encode())
else:
c.send('please use the correct admin commands'.encode())
return
def handle_client(c,a): #This works(game)
def within(vaule,goal,n):
if abs(goal - vaule)<= n:
return True
else:
return False
while True:
rmd = random.randrange(0,30)
print('The random number is',rmd) # radom number
hello = c.recv(78).decode()
if hello == "Hello\r\n":
c.send('Greetings\r\n'.encode())
else:
c.send('ERROR\r\n'.encode())
game = c.recv(80).decode()
if game == "Game\r\n":
c.send('Ready\r\n'.encode())
else:
c.send('ERROR\r\n'.encode()) # change this
# hand shake communcation works
while True:
geuss = re.findall('\d+',c.recv(80).decode())
print(geuss)
geuss1 = int(''.join(map(str,geuss)))
print(geuss1)
checker = within(geuss1,rmd,2)
if geuss1 == rmd:
c.send("Correct\r\n".encode())
c.close()
return
elif checker == True:
c.send("Close\r\n".encode())
else:
c.send("Far\r\n".encode())
c.close()
return
admin = 4001
client = 4000
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM,)
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM,)

Sending strings from a list over a socket to be displayed in real time

My list contains IP addresses and port numbers of connected clients to my program. The admin threads role is to send each currently connected clients IP address and port number to an admin client in this string format - eg '172.0.0.1 1234'. Could I have some advise on how to send each each address so that it only shows currently connected addresses and port numbers on the admin client program.
addressList is a global variable list
Here is my code-
Server
import threading
import socket
import math
import random
import ssl
addressList = []
def within(guess,goal,n):
absValue = abs(guess - goal)
if absValue <= n:
return True
else:
return False
def HandleAdmin(adminSocket,):
global addressList
(c,a) = adminSocket.accept()
ts = ssl.wrap_socket(c, certfile="5cc515_server.crt",
keyfile="5cc515_server.key",
server_side=True,
cert_reqs=ssl.CERT_REQUIRED,
ca_certs="5cc515-root-ca.cer")
if ts.recv(80).decode() == 'Hello\r\n':
ts.send('Admin-Greetings\r\n'.encode())
if ts.recv(80).decode() == 'Who\r\n':
for addr in addressList:
ts.send(addr).encode()
ts.close()
return
def HandleClient(c,a):
global addressList
address, port = a
address = str(address) + ' ' + str(port)
addressList.append(address)
scoreCount = 0
guess = 0
if(c.recv(80).decode()) == 'Hello\r\n':
c.send('Greetings\r\n'.encode())
goal = random.randrange(1,21)
while guess!= goal:
guess =c.recv(80).decode()
guess = int(guess[7:len(guess)-2])
if guess == goal:
c.send('Correct\r\n'.encode())
elif within(guess, goal, 2) == True:
c.send('Close\r\n'.encode())
else:
c.send('Far\r\n'.encode())
c.close()
return
clientSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientSocket.bind(("127.0.0.1",4000))
clientSocket.listen(5)
adminSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
adminSocket.bind(("127.0.0.1",4001))
adminSocket.listen(5)
handleAdminThread = threading.Thread(target = HandleAdmin,
args = (adminSocket,))
handleAdminThread.start()
while True:
(c,a) = clientSocket.accept()
clientThread = threading.Thread(target = HandleClient, args = (c,a))
clientThread.start()
Admin Client
import ssl
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ts = ssl.wrap_socket(s, certfile="100298750.crt",
keyfile="100298750.key",
ca_certs="5cc515-root-ca.cer")
ts.connect(('127.0.0.1', 4001))
ts.send("Hello\r\n".encode())
addressList = []
if ts.recv(80).decode() == "Admin-Greetings\r\n":
print("The players currently playing are:\n\n")
ts.send("Who\r\n".encode())
while True:
print(ts.recv(80).decode())
In your HandleClient function, c.close() means the client has disconnected.
So, to let your admin know they did, you have to remove that address from the 'addressList' (since when you send "Who\r\n" your addressList list is referred to).
So, after c.close() you should write:
addressList.remove(address)

Categories

Resources