getting an error when try to pass the messege to client - python

sir, i am developing an server client appication using python. but when i run the server it just works fine and when i run the client, in the server i am getting an error saying
conn.sendall(reply)
TypeError: a bytes-like object is required, not 'tuple'
it seems like server cannot reply the messege to client. but i have no idea how to solve it. please anyone help me... here is my server code:
import socket
import sys
HOST = '127.0.0.1'; # Symbolic name meaning all available interfaces
PORT = 2014; # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ("Socket created")
print ("Socket bind complete")
s.bind((HOST, PORT))
s.listen(10)
print ("Socket now listening")
#now keep talking with the client
while True:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print ("Connected with ", addr[0] ,":" , str(addr[1]))
data = conn.recv(1024)
reply = ("O", data)
if not data:
break
conn.sendall(reply)// here it comes the error, i have used encode.('utf-8') but no luck
conn.close()
s.close()

Related

How to write a python echo server that doesn't disconnect after first echo?

I want to set up a simple echo server that just echoes back whatever the client sends to it. However, currently the server disconnects (the server socket closes) after it echoes back the first client message. I want to be able to "chat" continuously with the server, where the server just echoes back several consecutive messages I send without disconnecting; e.g.:
"Hi there!"
"Echoing: Hi there!"
"How are you?"
"Echoing: How are you?"
"Cheers!"
"Echoing: Cheers!"
etc.
Currently I have the following code:
server.py:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
client.py:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Echoing: ', repr(data))
The server, however, disconnects after it echoes back the first client message (probably because of the if not data: break statement).
P.S. I'd appreciate any additional explanations which might be necessary - this example has educational purposes, so I'm not (only) after getting the code running.
Thanks!
server.py:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
if data.decode() == "bye":
break
conn.sendall(data)
conn, addr = s.accept()
I will show you the code I created then talk you through it:
Server:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
conn.sendall(data)
For the server I removed:
if not data:
break
It simply wasn't working for me. If you know your message is going to be less than the 1024 bytes( which here it is) it's unnecessary. But if you want a longer message change that value to a bigger number to accommodate. So yes you were right in suspecting it was that line.
Client:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
print("Connected")
while True:
print("Sending data")
s.sendall(b'Hello, world')
print("Recieving data")
data = s.recv(1024)
print('Echoing: ', repr(data))
For the client side I just added the send and receive process into a loop.
Things to note:
This only works for me when run through the terminal, I don't know if you know how to do that so sorry if you do, here's a link explaining:
https://www.wikihow.com/Use-Windows-Command-Prompt-to-Run-a-Python-File
I assumed you use Windows.
You will need to follow the process for both your client.py programme and server.py programme. Make sure you run the server.py programme first.
This will cause an infinite loop of sending and receiving. Press Ctrl+C to terminate.
I hope this solves your problem and you can edit the code accordingly. Any further problems please do comment and I'll try to get back to you.
Maybe use sleep instead of break
if not data:
time.sleep(1)
continue
You have to import time module for this.

Python s.recv() returns empty string

I've got a simple client and server I found on an online tutorial
#server.py
import socket # Import socket module
s = socket.socket() # Create a socket object
host = 'localhost' # Get local machine name
port = 12345 # Reserve a port for your service.
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
c.send('Thank you for connecting')
c.close() # Close the connection
#client # This is client.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = 'localhost'
port = 12345 # Reserve a port for your service.
s.connect((host, port))
print s.recv(1024)
s.close # Close the socket when done
When I run my client.py all it does is print an empty string when it should print ('Thank you for connecting'). When I connect localhost 12345 from telnet it sends the message fine so I don't know why my client isn't receiving the message
Any thoughts. I'm very new to socket programming and would love to find a solution so I can move on.
While running your script as is, I got this error:
Waiting connections ...
Got connection from ('127.0.0.1', 63875)
Traceback (most recent call last):
File "serv.py", line 14, in <module>
c.send('Thank you for connecting')
TypeError: a bytes-like object is required, not 'str'
Few things here:
Ensure you're sending bytes instead of str. you could do this by replacing line 14 with:
c.send(b'Thank you for connecting')
Also, it's always useful to declare your sockets s like this:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Further read:
Py2: https://docs.python.org/2/library/socket.html
Py3: https://docs.python.org/3/library/socket.html
Hope it works! :)

using select() method for client/ server chat in Python

I am writing a client/ server program in Python where, once the client and server have successfully connected via a socket, they may exchange messages. Below is my server and client code. When compiled, the connection is established correctly and the messages are sent successfully, but one cannot send a second message until it has received a response from the other party.
For example:
Client sends: "Hello, server!"
Server sends: "I have received your message, client!"
Client sends: "great, here's another one"
Client sends: "and a second one!"
At this point, the server terminal window has received the message saying "great, here's another one", but must first reply to this message before receiving "and a second one!".
I think my issue is that I need to use the select() method, but do not understand how to do so. How can I fix this?
#The server code
HOST = ''
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
print("Now listening...")
s.listen(1) #only needs to receive one connection (the client)
conn, addr = s.accept() #accepts the connection
print("Connected by: ", addr) #prints the connection
i = True
while i is True:
data = conn.recv(1024) #receives data
print('Received:' , repr(data)) #prints the message from client
reply = raw_input() #server types a response
conn.sendall(reply) #server now sends response back to client
close()
below is the client code (client.py)
The client code
from socket import*
HOST = '192.168.41.1'
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
while True:
message = raw_input() #client's message to the server
s.send(message) #sends message to the server
print("Waiting for response...")
reply = s.recv(1024) #receives message from server
print("New message: " + repr(reply)) #prints the message received
close()
Look at the following examples:
http://code.activestate.com/recipes/531824-chat-server-client-using-selectselect/
and
http://www.binarytides.com/code-chat-application-server-client-sockets-python/
also some similar answer here:
Python client side in chat
What you are missing is select on client side where its select if to handle input from server or from command line.
So in that case, you don't have to wait for server response and can send 2 calls one after another from the client.
Freely adapting the answers above to what you wished to accomplish.
(I didn't test it - so make sure to check it)
from socket import*
import sys
import select
HOST = '192.168.41.1'
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
while True:
socket_list = [sys.stdin, s]
# Get the list sockets which are readable
read_sockets, write_sockets, error_sockets = select.select(
socket_list, [], [])
for sock in read_sockets:
#incoming message from remote server
if sock == s:
data = sock.recv(1024)
if not data:
print('\nDisconnected from server')
break
else:
#print data
sys.stdout.write(data)
# prints the message received
print("New message: " + repr(data))
prompt()
#user entered a message
else:
msg = sys.stdin.readline()
s.send(msg)
prompt()
s.close()
I would strongly suggest reading and familiarizing with this document and especially the non-blocking sockets part.
Your code now blocks when waiting for the data to arrive from the user. You want to instruct your program to wait for the data from the socket and at the same time allow user to type input.

Reuse the same socket to send and receive (Python)

I have written a simple script to send and receive messages using the Python socket module. I want to first send a message using sendMsg and then receive a response using listen. sendMsg works fine but when my server sends a response I receive the error:
"[WinError 10038] An operation was attempted on something that is not a socket"
I close the socket connection in sendMsg and then try to bind it in listen, but it's at this line that the error is produced. Please could someone show me what I am doing wrong!
import socket
port = 3400
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), port))
def sendMsg():
print("\nSending message:\n\n")
msg = ("Sample text").encode("utf-8")
s.send(msg)
s.close()
def listen():
s.bind(("", port))
s.listen(1)
serverSocket, info = s.accept()
print("Connection from", info, "\n")
while 1:
try:
buf = bytearray(4000)
view = memoryview(buf)
bytes = serverSocket.recv_into(view, 4000)
if bytes:
stx = view[0]
Size = view[1:3]
bSize = Size.tobytes()
nTuple = struct.unpack(">H", bSize)
nSize = nTuple[0]
message = view[0:3+nSize]
messageString = message.tobytes().decode("utf-8").strip()
messageString = messageString.replace("\x00", "")
else:
break
except socket.timeout:
print("Socket timeout.")
break
sendMsg()
listen()
Note: I have implemented listen in a separate client and used the line
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 3)
before s.bind() and s.connect(). This works OK. It would be nice to have it all in one client though.
As per the docs the socket.close() will close the socket and no further operations are allowed on it.
So in your code this line s.close() is closing the socket.
Because of that the s.bind(("", port)) will not work as the socket s is already closed!

Restart socket server in python

I've wrote a simple socket server in python (OS X). I want the server to restart when a client terminate the communication, so that the client can do a reconnect to the server. Look at the code below, what do i have to do at the "lost contact" IF? I'm completely new to Python.
Here is the code:
import socket
import os
s = socket.socket()
host = socket.gethostname()
port = 5555
os.system('clear')
print 'Server started'
print 'Waiting'
s.bind((host, port))
s.listen(5)
c, addr = s.accept()
print 'Contact', addr
while True:
msg = c.recv(1024)
if not msg:
s.close
print "Lost contact"
exit ()
else:
print msg
I dont know if you ever found your answer but i found this when i was searching for the same problem. I was trying to reset the socket on the server so that I could connect to the next client so i tried using socket.close() and then reinitializing the whole socket, but you actually don't need to do anything on the server side, just use socket.close() on the client side and another client can connect without screwing up the server (I realize this probably doesnt help you much now but in case anyone else did what i did I wanted them to know)
If I got you, you want to listen again when client gets disconnected so this should do its job:
import socket
import os
s = socket.socket()
host = socket.gethostname()
port = 5555
os.system('clear')
print 'Server started'
print 'Waiting'
def server():
s.bind((host, port))
s.listen(5)
c, addr = s.accept()
print 'Contact', addr
while True:
msg = c.recv(1024)
if not msg:
s.close
print "Restarting..."
server()
else:
print msg

Categories

Resources