When trying to send and decode an integer using socketserver and port, I get the following error ValueError: invalid literal for int() with base 10: '' (full stack trace at end). I marked the place where the error is with #<----- in the client. Note that I've tried all of the following: Increasing the buffer size, sending it as a string, trying every caste I could think of (to string then int, to float, to int before sending it, to byte then to int, etc.) though I may have missed one.
This is the code for my server:
import socketserver
import threading
import gameplayer
class GameServer:
class GameServerUDPHandler(socketserver.BaseRequestHandler):
def handle_register(self, socket, client_address):
number = len(self.server.base.players) # Zero based
number = number + 1 # One based
socket.sendto(bytes(number), client_address)
self.server.base.players[number] = gameplayer.GamePlayer(id=number)
print(self.server.base.players)
def handle(self):
data = self.request[0].strip()
data = str(data, 'utf-8')
print(data)
socket = self.request[1]
data = data.split('\n')
option = data[0]
print(option)
c_add = self.client_address
if option == "register":
self.handle_register(socket, c_add)
print("test")
elif option == "get_postion":
handle_get_postion(socket, c_add, data[1])
elif option == "change_postion":
hande_changed_postion(socket, c_add, data[1])
# print("{} wrote:".format(self.client_address[0]))
# socket.sendto(data.upper(), self.client_address)
def __init__(self, port):
self.server = socketserver.UDPServer(("localhost", port), self.GameServerUDPHandler)
self.server.base = self
self.players = {}
def start_server(self):
threading.Thread(target=self.server.serve_forever).start()
And my client (where the error is):
class GameClient:
def __init__(self, port, host):
self.port = port
self.host = host
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def register(self):
self.socket.sendto(bytes("register\n", "utf-8"), (self.host, self.port))
self.numberID = int(self.socket.recv(10240).strip()) #<- WHERE ISSUE IS
print("Received: {}".format(self.numberID))
Full Output (Error starts at part marked):
register
register
{1: <gameplayer.GamePlayer object at 0x10078e390>}
test
Traceback (most recent call last): #<---- Where the error starts in the output.
File "main.py", line 8, in <module>
client.register()
File "/Users/Mike/Desktop/Main/Programming/Work Space/Python/Game/gameclient.py", line 12, in register
self.numberID = int(self.socket.recv(10240))
ValueError: invalid literal for int() with base 10: ''
Change following line in the server code:
socket.sendto(bytes(number), client_address)
with:
socket.sendto(str(number).encode('utf-8'), client_address)
>>> bytes(3)
b'\x00\x00\x00'
>>> str(3)
'3'
>>> str(3).encode('utf')
b'3'
And the cause of the traceback
>>> int(bytes(3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: ''
Related
I've been trying to build a basis for some simple networking, and I keep running into an issue of WinError 10022. Here's my class:
class SocketFactory:
def __init__(self, secret):
self.secret = secret
def send(self, port, e_type, h_type, msg, ip="127.0.0.1"):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print("Socket object successfully created.\n")
s.bind((ip, port))
print("Socket bound to port \n")
while True:
c, addr = s.accept()
print('Connection established with ', addr)
if h_type == 1:
header = self.secret
c.send(header, "utf-8")
else:
print("Incorrect header type. Exiting...\n")
exit()
if e_type == 1:
c.send(bytes(msg, "utf-8"))
else:
print("Incorrect encoder type. Exiting...\n")
exit()
c.close()
The preliminary driver code is this:
from sockfactory import SocketFactory
print("Initializing masterserver setup...\n")
port = int(input("Enter port number: \n"))
#ip = str(input("Enter IPv4 address: \n"))
e_type = int(input("The encoding table for outbound bytes will be: \n" "1 = UTF-8 \n"))
h_type = int(input("The immutable header packet type will be: \n" "1 = Simple \n"))
msg = str(input("Enter packet payload: \n"))
secret = b'10000000011000101011110'
SocketFactory.send(port, e_type, h_type, msg, "127.0.0.1")
And the error message:
Traceback (most recent call last):
File "C:/Users/EvESpirit/PycharmProjects/aaa/main", line 13, in <module>
SocketFactory.send(port, e_type, h_type, msg, "127.0.0.1")
File "C:\Users\EvESpirit\PycharmProjects\aaa\sockfactory.py", line 19, in send
self.c, self.addr = s.accept()
File "C:\Users\EvESpirit\AppData\Local\Programs\Python\Python38\lib\socket.py", line 292, in accept
fd, addr = self._accept()
OSError: [WinError 10022] An invalid argument was supplied
Can anyone help me here? What am I doing wrong and how can I do it better? Thank you.
You're missing s.listen() between s.bind() and s.accept():
>>> from socket import *
>>> s=socket()
>>> s.bind(('',5000))
>>> s.accept()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python36\lib\socket.py", line 205, in accept
fd, addr = self._accept()
OSError: [WinError 10022] An invalid argument was supplied
>>> s.listen()
>>> s.accept() # waits here for a connection
I am building a basic python web server, but I keep having a problem where it is not sending any data (by the way I am accessing the website on the same computer as it is running on and I have the file which the server is trying to access) here is my code:
import socket
HOST, PORT = '', 80
def between(left,right,s):
before,_,a = s.partition(left)
a,_,after = a.partition(right)
return a
filereq = ""
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
lines = []
print("Started!")
listen_socket.listen(1)
print("Listening")
while True:
try:
lines = []
client_connection, client_address = listen_socket.accept()
print("Connected")
request = client_connection.recv(1024)
print("Received Data!")
filereq = between("GET /", " HT", request)
print(filereq)
filereq = open(filereq)
for line in filereq:
lines.append(line)
print(lines)
sendata = ''.join(lines)
print(sendata)
http_response = """\
HTTP/1.1 200 OK
{}
""".format(sendata)
print(http_response)
client_connection.sendall(http_response)
print("Sent the Data!")
client_connection.close()
print("Connection Closed!")
except:
5+5
The problem is that the server is implemented in Python3 but the code mixes bytes and strings, which works in Python2 but not Python3.
This causes an error in the between function, because partition is being called on a bytes object but is being provided with str separator values.
>>> data = b'abc'
>>> data.partition('b')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'str'
To fix this, decode the data from bytes to str when read from the socket, then encode back to bytes before sending the response (socket.sendall expects bytes as an argument).
Also, print out any exceptions that occur so that you can debug them.
import socket
import sys
import traceback
HOST, PORT = '', 80
def between(left,right,s):
before,_,a = s.partition(left)
a,_,after = a.partition(right)
return a
filereq = ""
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
lines = []
print("Started!")
listen_socket.listen(1)
print("Listening")
while True:
try:
lines = []
client_connection, client_address = listen_socket.accept()
print("Connected")
request = client_connection.recv(1024)
print("Received Data!")
# Decode the data before processing.
decoded = request.decode('utf-8')
filereq = between("GET /", " HT", decoded)
print(filereq)
filereq = open(filereq)
for line in filereq:
lines.append(line)
print(lines)
sendata = ''.join(lines)
print(sendata)
http_response = """\
HTTP/1.1 200 OK
{}
""".format(sendata)
print(http_response)
# Encode the response before sending.
encoded = http_response.encode('utf-8')
client_connection.sendall(encoded)
print("Sent the Data!")
client_connection.close()
print("Connection Closed!")
except Exception:
# Print the traceback if there's an error.
traceback.print_exc(file=sys.stderr)
I'm trying to use the sniff() function that scapy provides but it raises the following error:
Traceback (most recent call last):
File "TestCode.py", line 54, in <module>
packets = getMessege()
File "TestCode.py", line 45, in getMessege
return sniff(count=getLen(), lfilter=filterFrom)
File "C:\Heights\PortableApps\PortablePython2.7.6.1\App\lib\site-packages\scapy\sendrecv.py", line 575, in sniff
sel = select([s],[],[],remain)
select.error: (10038, 'An operation was attempted on something that is not a socket')
Here is the code (FromGlobal is a tuple that contains the IP and Port of the sender):
def getLen():
while True:
length, LenFrom = sock.recvfrom(1024)
try:
IntLen = int(length)
except:
pass
else:
if LenFrom == FromGlobal:
return IntLen
def filterFrom(pck):
try:
return pck[IP].src == FromGlobal[0] and pck[UDP].sport == FromGlobal[1]
except:
return False
def getMessege(): # TODO This needs to return only the messege and port
return sniff(count=getLen(), lfilter=filterFrom)
packets = getMessege()
print packets.show()
The weird part is that if I try to do it like so:
def func1():
return int('1')
def lfilter(pack):
return TCP in pack and pack[IP].src != '8.8.8.8'
def func():
return sniff(count=func1(), lfilter=lfilter)
var = func()
print var.show()
it works perfectly well. If someone could point out the difference between the two it would help a lot.
I'm use WinPcap 4.1.3 and scapy 2.x.
Well, Resolved it myself. apparently if you do:
from scapy.all import *
from scapy.layers.inet import *
the sniff function won't works so do only
from scapy.all import *
I've been trying everything I can to run this code, but I can't figure out what the issue is. It's a server/client chat program in python 3. The error I'm getting is:
Traceback (most recent call last):
File "/home/nate/Desktop/soc_chat/server_soc.py", line 48,<module>
handler = ClientHandler(client, record)
NameError: name 'record' is not defined
I'm not sure how I can fix this issue. Any help would be great. I'm on ubuntu, with python 3 installed. I've tried running the code as 'python3 myFile.py' in the terminal instead of 'python myFile.py' also to make sure it's not trying to run it as python 2. As I said, any help would be greatly appreciated.
Here's the code(server side):
from socket import *
from codecs import decode
from chatrecord import ChatRecord
from threading import Thread
from time import ctime
class ClientHandler(Thread):
def __init__(self, client, record):
Thread.__init__(self)
self._client = client
self._record = record
def run(self):
self._client.send(bytes('Welcome', CODE))
self._name = decode(self._client.recv(BUFSIZE), CODE)
self._client.send(bytes(str(self._record), CODE))
while True:
message = decode(self._client.recv(BUFSIZE), CODE)
if not message:
print('Client disconnected')
self._client.close()
break
else:
message = self._name + '' + \
ctime() + '\n' + message
self._record.add(message)
self._client.send(bytes(str(self._record), CODE))
HOST = 'localhost'
PORT = 5000
BUFSIZE = 1024
ADDRESS = (HOST, PORT)
CODE = 'ascii'
server = socket(AF_INET, SOCK_STREAM)
server.bind(ADDRESS)
server.listen(5)
while True:
print('Waiting for connection...')
client, address = server.accept()
print('...connected from:', address)
handler = ClientHandler(client, record)
handler.start()
Code(Client Side):
from socket import *
from codecs import decode
HOST = 'localhost'
PORT = 5000
BUFSIZE = 1024
ADDRESS = (HOST, PORT)
CODE = 'ascii'
server = socket(AF_INET, SOCK_STREAM)
server.connect(ADDRESS)
print(decode(server.recv(BUFSIZE), CODE))
name = input('Enter your name: ')
server.send(bytes(name, CODE))
while True:
record = decode(server.recv(BUFSIZE), CODE)
if not record:
print('server disconnected')
break
print(record)
message = input('> ')
if not message:
print('Server disconnected')
break
server.send(bytes(message, CODE))
server.close()
Code(chatrecord.py)
class ChatRecord(object):
def __init__(self):
self.data = []
def add(self, s):
self.data.appent(s)
def __str__(self):
if len(self.data) == 0:
return 'No messages yet!'
else:
return '\n'.join(self.data)
I'm going to go out on a limb and say you forgot the following line:
record = ChatRecord()
You import the class but never use it in the server-side code.
Note that you misspelled list.append() in the ChatRecord.add() method:
def add(self, s):
self.data.appent(s)
# ^
I'm trying to write a client-server program where server receives the requests for a database records, or files, and sends it back. Everything was working just fine until I used the pickle function to send data from client to server,
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "server.py", line 71, in run
data = pickle.loads(data)
File "/usr/lib/python2.7/pickle.py", line 1381, in loads
file = StringIO(str)
TypeError: expected read buffer, NoneType found
When I send data from server to client, there is no problem. I worked like this for a few weeks but when there is about 50 exceptions, the server program closes.
client.py file:
import socket
import sys
import time
import pickle
import struct
def recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = ''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data
def recv_msg(sock):
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
def sending(msg):
host = 'localhost'
port = 50000
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
lenght = len(msg)
if lenght>0:
msg = pickle.dumps(msg)
msg = struct.pack('>I', len(msg)) + msg
s.sendall(msg)
print 'sended string lenght: '+str(lenght)
else:
s.send('nothing sended')
data = recv_msg(s)
lenght2 = len(data)
print data
print 'received string lenght: '+str(lenght2)
#sys.stdout.write(data)
s.close()
while 1:
msg = raw_input('Input:')
sending(msg)
server.py:
class Client(threading.Thread):
def __init__(self,(client,address)):
threading.Thread.__init__(self)
self.client = client
self.address = address
self.size = 1024
def run(self):
running = 1
while running:
sock = self.client
data = self.recv_msg(sock)
data = pickle.loads(data)
if data:
msg = struct.pack('>I', len(data)) + data
self.client.sendall(msg)
else:
self.client.close()
running = 0
def recv_msg(self, sock):
# Read message length and unpack it into an integer
raw_msglen = self.recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return self.recvall(sock, msglen)
def recvall(self, sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = ''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data
In previous version I puted the pickle function from server to client, and it worked fine, no problems, but now I started to write it from the beginning to find the problem, but I didn't.
The recv_msg method was found here:
Python Socket Receive Large Amount of Data
The recv_msg method returns None when EOF is reached, and you pass that None to pickle.loads, which is an error.
To fix the problem, place the call to pickle.loads() after the EOF-check:
data = self.recv_msg(sock)
if data is not None:
data = pickle.loads(data)
msg = struct.pack('>I', len(data)) + data
self.client.sendall(msg)
else:
self.client.close()
running = 0