I am a newbie to socket programming and I want to send two numbers from client side to server side in UDP and the server will return the product of the two numbers.
When I send the numbers from the client side, there is an error on the server side that "bytes object has no attribute recvfrom".
This is my code
Client side
from socket import socket, AF_INET, SOCK_DGRAM
c = socket(AF_INET, SOCK_DGRAM)
c.connect(('localhost', 11111))
num1 = input('Input a number: ')
num2 = input('Enter a second number: ')
c.sendto(num1.encode('utf-8'), ('localhost', 11111))
c.sendto(num2.encode('utf-8'), ('localhost', 11111))
print(c.recvfrom(1024).decode())
Server side
from socket import socket, AF_INET, SOCK_DGRAM
s = socket(AF_INET, SOCK_DGRAM)
print('Socket created!')
s.bind(('localhost', 11111))
while True:
c, addr = s.recvfrom(1024)
num1 = c.recvfrom(1024)
num2 = c.recvfrom(1024)
print('Received from client having address:', addr)
print('The product of the numbers sent by the client is:', num1*num2)
s.sendto(bytes('***Welcome To The Server***', 'utf-8'))
This is the error that I get:
Exception has occurred: AttributeError
'bytes' object has no attribute 'recvfrom'
File "C:\Users\kryptex\Downloads\Compressed\attachments\udpserv1.py", line 11, in <module>
num1 = c.recvfrom(1024)
c, addr = s.recvfrom(1024)
num1 = c.recvfrom(1024)
num2 = c.recvfrom(1024)
c are the bytes returned by the s.recvfrom. You likely meant s.recvfrom instead of c.recvfrom. Hint: give your variables more clear and longer names which describe their actual function.
Apart from that it is unclear to me what the intend of c, addr = s.recvfrom(1024) actually is, since there is no matching send on the client side. I have the feeling that you are confusing TCP and UDP sockets and tried to implement some kind of TCP accept here, matching the c.connect on the client side. This is wrong though.
Related
What I'm trying to create are a set of server and client scripts; the server script prompts a user for raw input, stores that input in a dictionary and converts it to json with the json.dumps() function. The converted dictionary is then stored in the jasonFile variable which is then sent to the client. The json dictionary is working but I'm struggling with the networking side of things.
Here is my server code:
def Main():
host = '0.0.0.0'
port = 5000
s.bind((host, port))
s.listen(5)
print "Server Started"
while True:
addr = s.accept()
print "Client Connected from IP: " + str(addr)
serverMessage = "Connection Established: Would you like to download the Json dictionary?"
s.send(serverMessage)
clientReply = s.recv(1024)
if clientReply in ['Y', 'y', 'Yes', 'yes', 'YES']:
s.send(jasonFile)
s.close()
else:
print "Connection from " + addr + " closed!"
s.send("Connection Error!")
s.close()
And here is my client code:
def Main():
host = raw_input("Please enter the server IP you wish to connect to: ")
port = 5000
#define client to use socket module to connect via IPV4 and TCP only
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
serverMessage = client.recv(1024)
print serverMessage
clientReply = raw_input("Type 'Yes' To download dictionary")
if clientReply in ['Y', 'Yes', 'y', 'yes', 'YES']:
client.send(clientReply)
jasonRecv = client.recv(1024)
print jasonRecv
else:
client.close()
print "Disconnected from server!"
I haven't gotten as far as converting the json data back to a string on the client yet because the server throws me an error when the client tries to connect.
The error message I get from IDLE is:
Server Started
Client Connected from IP: (<socket._socketobject object at 0x000000000401E048>, ('127.0.0.1', 34375))
Traceback (most recent call last): File "D:/Server.py", line 105, in <module>
Main()
File "D:/Server.py", line 94, in Main
s.send(serverMessage)
error: [Errno 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
I thought I was defining the address to send data to in the addr variable, but apparently not?
Try:
conn, addr = s.accept()
...
conn.send(serverMessage)
i.e. replace s. calls with conn. which represents the accepted socket connection from the client.
From the Python socket API:
socket.accept()
Accept a connection. The socket must be bound to an address and listening for connections.
The return value is a pair (conn, address) where conn is a new socket
object usable to send and receive data on the connection, and address
is the address bound to the socket on the other end of the connection.
Examples are provided at the end of the page.
Also see the Python Socket Programming Howto
I know that similar questions have been raised but they don't seem to work for me! I have tried serializing the dictionary then converting that to a string then encoding it before I send it over the socket. No success so far!
This is my server code:
#library
import socket
import pickle
#socket initialization
host = "127.0.0.1"
port = 5000
mainAddr = (host, port)
#dict initialization
dataDict = {} #just imagine that dict has content
#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.bind((mainAddr))
s.listen(4)
print('program started')
print('listening..')
while True:
try:
conn, addr = s.accept()
print("connection from: "+str(addr))
print("sending message..")
pickle.dumps(dataDict)
print('pickled!')
dataS = str(dataP)
print('stringed!')
dataE = dataS.encode('UTF-8')
print('encoded!')
s.sendto(dataE,addr)
print('data sent!')
except:
pass
s.close()
For the socket initialization, I've tried other types:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP
s = socket.socket()
For the sending part, I've tried these alternatives:
s.send(dataE)
s.send(dataE,addr)
s.sendall(dataE)
s.sendall(dataE,addr)
When I run the program, these get printed out:
program started
listening..
connection from:<insert addr here>
sending message..
pickled!
stringed!
encoded!
Only data sent! is not sent. So I am guessing that it's the sending part that has a problem.
For the client side, here's the code:
#library
import socket
import pickle
#initialization
host = '127.0.0.1'
port = 5000
buffer = 1024
#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.connect((host,port))
print('connected!')
#receive dictionary
print('receiving message..')
while True:
data, addr = s.recvfrom(buffer)
print('received!')
dataD = data.decode("UTF-8")
print('decoded!')
dataP = pickle.loads(dataD)
print('unpickled!')
print(str(dataP))
s.close()
In the client terminal, only the following prints:
connected!
receiving message..
On the client side, I've tried changing the order of unpickling and decoding but still, to no avail.
A TCP server socket is not actually used for sending/receiving data; I'm surprised you're not getting an error when calling s.send() or similar on it. Instead, it's a factory for producing individual sockets for each client that connects to the server - conn, in your code. So, conn.sendall() is what you should be using. No address parameter is required, the individual socket already knows who it is talking to. (.send() is unreliable without some extra work on your part; .sendto() is only used with UDP sockets that have not been connected to a particular client.)
I'm making a simple Python application which will allow people to communicate with each other through a CLI. I am relatively new to the sockets module, however my code has no problems. Except for one. When I run my two scripts (chatclient.py and chatserver.py), they run fine. The server starts up, and the client will ask the user for their name and the message. However upon clicking enter to send the message, i receive:
TypeError: decoding str not supported
I have tried using .encode('utf-8)/ .decode('utf-8') but still the same error. The code will be below (with multi comments around the 'wrong' code).
#client.py
import socket
import threading
import time
tLock = threading.Lock() #creates a lock for the thread and prevents output to the screen
shutdown = False
def receiving(name, sock):
while not shutdown: #while the program is still running
try:
tLock.acquire() #acquires the lock
while True:
data, addr = sock.recv(1024).decode('utf-8') #gets the data and address from the data received
print(str(data))
except:
pass
finally:
tLock.release() #releases the lock
host = "127.0.0.1" #uses localhost as the host
port = 0 #picks up any free port on the computer
server = ("127.0.0.1",5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
s.setblocking(0)
rt = threading.Thread(target=receiving, args=("RecvThread", s))
rt.start()
'''name = input("Enter your name: ")
message = input("> ")
while message != "q":
if message != '':
print("From ",name)
s.sendto(str(name, message), (host,port)).decode('utf-8')'''
tLock.acquire()
message = input('')
tLock.release()
time.sleep(0.5)
shutdown = True
rt.join()
s.close()
^^^client
#server.py
import socket
import time
host = "127.0.0.1" #makes localhost the host server
port = 5000 #uses any random port between 1024 and 65535
clients = []
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #creates a new socket object
s.bind((host,port)) #binds the host and port to socket object
s.setblocking(0) #sets the blocking to 0 (essentially no blocking)
quitting = False
print("The server has now started on ",time.ctime(time.time()))
while not quitting: #while quitting hasn't happened
try:
data, addr = s.recvfrom(1024).decode('utf-8') #tries to get data and address from the data coming in
if "Quit" in data: #if the data has quit in it
quitting = True #quitting = true meaning the while not quitting loop would break
if addr not in clients: #if the address given is not in the list 'Clients'
clients.append(addr) #then it will append it to the list
print(time.ctime(time.time()),"- ",str(addr).decode('utf-8')," : ",str(data).decode('utf-8')) #prints the time, the address and the message
for client in clients: #for each client in the list of clients
s.sendto(bytes(data, 'utf-8')) #send the data to the clients
s.sendto(bytes(client, 'utf-8'))
except:
pass
s.close()
^^^server
If you pass 2 or more values to str, it tries to decode, but in your case, the first argument is already string object (because the return value of input function is string); causes the error.
>>> str('a')
'a'
>>> str('a', 'utf-8') # trying to decode (the 2nd arg. is encoding)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: decoding str is not supported
>>> str(b'a', 'utf-8')
'a'
Beside that, you need to pass bytes object to socket.sendto as the first argument. Encode string to get a bytes object:
>>> 'a'.encode() # You can omit encoding arg.; `utf-8` is default in Python 3.x
b'a'
>>> 'a'.encode('utf-8')
b'a'
Replace following line of client code:
s.sendto(str(name, message), (host,port)).decode('utf-8')
with:
s.sendto('{}: {}'.format(name, message).encode('utf-8'), (host,port))
data, addr = s.recvfrom(1024).decode('utf-8')
Above line is also wrong. socket.recvfrom(..) returns a tuple of (message, address). The tuple does not have decode method. You need to decode message only.
data, addr = s.recvfrom(1024)
data = data.decode('utf-8')
server
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('127.0.0.1', 5000))
print("The server has now started on ", time.ctime())
clients = []
while True:
data, addr = s.recvfrom(1024)
text = data.decode('utf-8')
if "Quit" in text:
break
if addr not in clients:
clients.append(addr)
print(time.ctime(), "-", addr, ":", text)
for client in clients:
s.sendto(data, client)
s.close()
Consider the following example.
from socket import *
msg = input("Please enter your name ")
msg = msg.encode()
myHostIp = ''
myHostPort = 54040
socket_obj = socket(AF_INET, SOCK_STREAM)
socket_obj.bind((myHostIp,myHostPort))
socket_obj.listen(5)
while True:
connection,address = socket_obj.accept()
print("Client : ",address)
connection.send(msg)
print(socket.getsockname(socket_obj))
print(socket.getsockname(connection))
print(socket.getpeername(socket_obj))
print(socket.getpeername(connection))
while True:
data = connection.recv(1024)
print("This was received from ", data)
connection.close()
In this simple program the output of line print(socket.getsockname(socket_obj)) was (0.0.0.0)
and of the print(socket.getpeername(socket_obj)) was socket_obj is not connected.
My question is: once connection,address = socket_obj.accept() is executed, is the control from socket_obj transferred to connection?
The socket you call .listen() on is a server socket; about all you can do with it is to call .accept() to produce a client socket, which handles all actual communications. One server socket can produce any number of client sockets over its lifetime.
I have two scripts, Server.py and Client.py.
I have two objectives in mind:
To be able to send data again and again to server from client.
To be able to send data from Server to client.
here is my Server.py :
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.3"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))
serversocket.listen(5)
print ('server started and listening')
while 1:
(clientsocket, address) = serversocket.accept()
print ("connection found!")
data = clientsocket.recv(1024).decode()
print (data)
r='REceieve'
clientsocket.send(r.encode())
and here is my client :
#! /usr/bin/python3
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host ="192.168.1.3"
port =8000
s.connect((host,port))
def ts(str):
s.send('e'.encode())
data = ''
data = s.recv(1024).decode()
print (data)
while 2:
r = input('enter')
ts(s)
s.close ()
The function works for the first time ('e' goes to the server and I get return message back), but how do I make it happen over and over again (something like a chat application) ?
The problem starts after the first time. The messages don't go after the first time.
what am I doing wrong?
I am new with python, so please be a little elaborate, and if you can, please give the source code of the whole thing.
import socket
from threading import *
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.1.3"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))
class client(Thread):
def __init__(self, socket, address):
Thread.__init__(self)
self.sock = socket
self.addr = address
self.start()
def run(self):
while 1:
print('Client sent:', self.sock.recv(1024).decode())
self.sock.send(b'Oi you sent something to me')
serversocket.listen(5)
print ('server started and listening')
while 1:
clientsocket, address = serversocket.accept()
client(clientsocket, address)
This is a very VERY simple design for how you could solve it.
First of all, you need to either accept the client (server side) before going into your while 1 loop because in every loop you accept a new client, or you do as i describe, you toss the client into a separate thread which you handle on his own from now on.
client.py
import socket
s = socket.socket()
s.connect(('127.0.0.1',12345))
while True:
str = raw_input("S: ")
s.send(str.encode());
if(str == "Bye" or str == "bye"):
break
print "N:",s.recv(1024).decode()
s.close()
server.py
import socket
s = socket.socket()
port = 12345
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print "Socket Up and running with a connection from",addr
while True:
rcvdData = c.recv(1024).decode()
print "S:",rcvdData
sendData = raw_input("N: ")
c.send(sendData.encode())
if(sendData == "Bye" or sendData == "bye"):
break
c.close()
This should be the code for a small prototype for the chatting app you wanted.
Run both of them in separate terminals but then just check for the ports.
This piece of code is incorrect.
while 1:
(clientsocket, address) = serversocket.accept()
print ("connection found!")
data = clientsocket.recv(1024).decode()
print (data)
r='REceieve'
clientsocket.send(r.encode())
The call on accept() on the serversocket blocks until there's a client connection. When you first connect to the server from the client, it accepts the connection and receives data. However, when it enters the loop again, it is waiting for another connection and thus blocks as there are no other clients that are trying to connect.
That's the reason the recv works correct only the first time. What you should do is find out how you can handle the communication with a client that has been accepted - maybe by creating a new Thread to handle communication with that client and continue accepting new clients in the loop, handling them in the same way.
Tip: If you want to work on creating your own chat application, you should look at a networking engine like Twisted. It will help you understand the whole concept better too.