Simple client - server app.
#Server use decode
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host,port))
s.listen(5)
while True:
c,addr = s.accept()
print("Got connection from " + str(addr))
ret_val = s.send("Thank you".encode('utf-8'))
print ("ret_val={}".format(ret_val))
c.close()
Client:
#client use decode
from socket import gethostname, socket
serSocket = socket()
server = gethostname()
port = 12345
serSocket.connect((server, port))
data = serSocket.recv(1024)
msg = data.decode('utf-8')
print("Returned Msg from server: <{}>".format(msg))
serSocket.close()
when the server tries to send the following exception occurred
Traceback (most recent call last):
Got connection from ('192.168.177.1', 49755)
File "C:/Users/Oren/PycharmProjects/CientServer/ServerSide/Server2.py", line 16, in <module>
ret_val = s.send("Thank you".encode('utf-8'))
OSError: [WinError 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
Process finished with exit code 1
As can be seen the client connects the server successfully.
But send fails.
What is the problem?
The problem is that you are sending on the listening socket, not on the connected socket. connect returns a new socket which is the one you must use for data transfer. The listening socket can never be used for sending or receiving data.
Change the send to this and your program will work fine:
ret_val = c.send("Thank you".encode('utf-8'))
(Note c.send, not s.send)
Related
I guess Python automatically send a close sign when shuts down(ctr+c) the client.
python tcp server
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 12345 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
#if not data:break
conn.sendall(data)
print(data)
python tcp client
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 12345 # The port used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', data)
#s.close()
When executing this code,
the server continues to receive null data (maybe close sign) by the client that ended without closing.
Connected by ('127.0.0.1', 55305)
b'Hello, world'
b''
b''
b''
b''
b''
...
This error occurs when run node.js client and shutdown(ctr+c) without close sign.
The python tcp server occurs error but not print null.
node.js tcp client
const Net = require('net');
const client = new Net.Socket();
client.setEncoding('utf8');
client.connect({ port: 12345, host: '127.0.0.1' })
client.write('Hello, world');
/*client.end()*/
Connected by ('127.0.0.1', 56685)
b'Hello, world'
Traceback (most recent call last):
File "C:/.../server.py", line 13, in <module>
data = conn.recv(1024)
ConnectionResetError: [WinError 10054]An existing connection was forcibly closed by the remote host
I know that the server and the client need to send and receive the exit sign,
but I wonder why the Python client automatically sends the close sign when it is closed.
Where can I get information about this?
I am trying to implement the code as written here:
https://www.geeksforgeeks.org/simple-chat-room-using-python/
I can get it to run properly but cannot find a way to close the connection. The code simply runs until I enter a keyboard interrupt. I'l like to implement a keyword that will shut down the client and server and free the port.
I've implemented the client code to exit if the message is "quit" but the same technique isn't working in the server code. I keep getting caught on the "conn, addr = server.accept()" line and it returns the error
Traceback (most recent call last):
File "newServer.py", line 66, in <module>
conn, addr = server.accept()
File "/Users/######/anaconda3/lib/python3.7/socket.py", line 212, in accept
fd, addr = self._accept()
ConnectionAbortedError: [Errno 53] Software caused connection abort
Any help would be appreciated!
Edit: Adding code
server.py:
import socket
import select
from _thread import *
import threading
import sys
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
"""
the first argument AF_INET is the address domain of the socket. This is used when we have an Internet Domain
with any two hosts
The second argument is the type of socket. SOCK_STREAM means that data or characters are read in a continuous flow
"""
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
IP_address = "127.0.0.1"
Port = 12230
server.bind((IP_address, Port))
#binds the server to an entered IP address and at the specified port number. The client must be aware of these parameters
server.listen(100)
#listens for 100 active connections. This number can be increased as per convenience
list_of_clients=[]
def clientthread(conn, addr):
conn.send("Welcome to this chatroom!".encode())
#sends a message to the client whose user object is conn
while True:
try:
message = conn.recv(2048).decode()
if message:
print ("<" + addr[0] + "> " + message)
message_to_send = "<" + addr[0] + "> " + message
broadcast(message_to_send,conn)
#prints the message and address of the user who just sent the message on the server terminal
else:
remove(conn)
except:
continue
def broadcast(message,connection):
for clients in list_of_clients:
if clients!=connection:
try:
clients.send(message.encode())
except:
clients.close()
remove(clients)
def remove(connection):
if connection in list_of_clients:
list_of_clients.remove(connection)
while True:
conn, addr = server.accept()
"""
Accepts a connection request and stores two parameters, conn which is a socket object for that user, and addr which contains
the IP address of the client that just connected
"""
list_of_clients.append(conn)
print (addr[0] + " connected")
#maintains a list of clients for ease of broadcasting a message to all available people in the chatroom
#Prints the address of the person who just connected
start_new_thread(clientthread,(conn,addr))
#creates and individual thread for every user that connects
conn.close()
server.close()
client.py
import socket
import select
import sys
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
IP_address = "127.0.0.1"
Port = 12230
server.connect((IP_address, Port))
while True:
# maintains a list of possible input streams
sockets_list = [sys.stdin, server]
""" There are two possible input situations. Either the
user wants to give manual input to send to other people,
or the server is sending a message to be printed on the
screen. Select returns from sockets_list, the stream that
is reader for input. So for example, if the server wants
to send a message, then the if condition will hold true
below.If the user wants to send a message, the else
condition will evaluate as true"""
read_sockets,write_socket, error_socket = select.select(sockets_list,[],[])
for socks in read_sockets:
if socks == server:
message = socks.recv(2048).decode()
print (message)
else:
message = input("Message: ")
server.send(message.encode())
print("<You>")
print(message)
server.close()
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! :)
It's my client:
#CLIENT
import socket
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conne.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
i=0
while True:
conne.connect ( ('127.0.0.1', 3001) )
if i==0:
conne.send(b"test")
i+=1
data = conne.recv(1024)
#print(data)
if data.decode("utf-8")=="0":
name = input("Write your name:\n")
conne.send(bytes(name, "utf-8"))
else:
text = input("Write text:\n")
conne.send(bytes(text, "utf-8"))
conne.close()
It's my server:
#SERVER
import socket
counter=0
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 3001))
sock.listen(10)
while True:
conn, addr = sock.accept()
data = conn.recv(1024)
if len(data.decode("utf-8"))>0:
if counter==0:
conn.send(b"0")
counter+=1
else:
conn.send(b"1")
counter+=1
else:
break
print("Zero")
conn.send("Slava")
conn.close()
))
After starting Client.py i get this error:
Traceback (most recent call last): File "client.py", line 10, in
conne.connect ( ('127.0.0.1', 3001) ) OSError: [Errno 9] Bad file descriptor
Problem will be created just after first input.
This program - chat. Server is waiting for messages. Client is sending.
There are a number of problems with the code, however, to address the one related to the traceback, a socket can not be reused once the connection is closed, i.e. you can not call socket.connect() on a closed socket. Instead you need to create a new socket each time, so move the socket creation code into the loop:
import socket
i=0
while True:
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conne.connect(('127.0.0.1', 3001))
...
Setting socket option SO_BROADCAST on a stream socket has no affect so, unless you actually intended to use datagrams (UDP connection), you should remove the call to setsockopt().
At least one other problem is that the server closes the connection before the client sends the user's name to it. Probably there are other problems that you will find while debugging your code.
Check if 3001 port is still open.
You have given 'while True:' in the client script. Are you trying to connect to the server many times in an infinite loop?
I have to create a web server in Python. Below is the code I am working on. When i execute it, I initially get no error and it prints "Ready to serve.." , but after opening a browser and running http://10.1.10.187:50997/HelloWorld.html (HelloWorld is an html file in the same folder as my python code, while 10.1.10.187 is my IP address and 50997) is the server port), I get a TypeError saying 'a bytes like object is required and not str". please help me in resolving this and kindly let me know if any other modifications are required.
#Import socket module
from socket import *
#Create a TCP server socket
#(AF_INET is used for IPv4 protocols)
#(SOCK_STREAM is used for TCP)
# Assign a port number
serverPort = 50997
serverSocket = socket(AF_INET, SOCK_STREAM)
#serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#print ("hostname is: "), gethostname()
#print ("hostname is: "), socket.gethostname()
# Bind the socket to server address and server port
serverSocket.bind(("", serverPort))
# Listen to at most 1 connection at a time
serverSocket.listen(1)
# Server should be up and running and listening to the incoming connections
while True:
print ("Ready to serve...")
# Set up a new connection from the client
connectionSocket, addr = serverSocket.accept()
try:
# Receives the request message from the client
message = connectionSocket.recv(1024)
print ("Message is: "), message
filename = message.split()[1]
print ("File name is: "), filename
f = open(filename[1:])
outputdata = f.read()
connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n")
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.send("\r\n")
# Close the client connection socket
connectionSocket.close()
except IOError:
# Send HTTP response message for file not found
connectionSocket.send("HTTP/1.1 404 Not Found\r\n\r\n")
connectionSocket.send("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n")
# Close the client connection socket
connectionSocket.close()
serverSocket.close()
The error I am exacly getting-
Ready to serve...
Message is:
File name is:
Traceback (most recent call last):
File "intro.py", line 56, in <module>
connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n")
TypeError: a bytes-like object is required, not 'str'
You need to convert the string you are sending into bytes, using a text format. A good text format to use is UTF-8. You can implement this conversion like so:
bytes(string_to_convert, 'UTF-8')
or, in the context of your code:
connectionSocket.send(bytes("HTTP/1.1 404 Not Found\r\n\r\n","UTF-8"))
connectionSocket.send(bytes("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n","UTF-8"))`