So I'm starting to work on a kind of Internet of Things project and the first issue I'm stumbling upon is having trouble in setting up a basic server. Using this guide, to do some initial tests, here is the code being used:
'''
Simple socket server using threads
'''
import socket
import sys
HOST = '' # Symbolic name, meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
s.close()
I can set the server up and it will listen on socket, but when i try to connect with telnet, it times out. Since I'm on a network in my college, could this be the reason why things aren't going through? I remember doing something like this in C a while back and it seemed to work then...
The code works, but doesn't send/receive from the client. The following modest change makes the server send beer tasty to any lucky clients.
source
'''
Simple socket server using threads
'''
import socket
import sys
HOST = '' # Symbolic name, meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
conn.send('beer tasty\n') # <==
conn.close()
s.close()
test with Netcat in Linux. (Telnet also should work)
test
$ echo beer | nc -q1 localhost 8888
Connected with 127.0.0.1:37484
beer tasty
Related
I want to restart the input('CLIENT >> ') when the client recieves a message from the server and the same for the server (the server and client being python scripts in this case)
client.py:
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
print('Connecting to ', host, port)
s.connect((host, port))
while True:
msg = input('CLIENT >> ')
s.send(msg.encode())
msg = str(s.recv(1024))
print('SERVER >> ', str(msg))
server.py:
import socket
s = socket.socket()
host = ''
port = 12345
print('Server started!')
print('Waiting for clients...')
s.bind((host, port))
s.listen(5)
c, addr = s.accept()
print('Got connection from', addr)
while True:
recieved = c.recv(1024)
print('\n', addr, ' >> ', str(recieved))
msg = input('SERVER >> ')
c.send(msg.encode())
NOTES:
Using my laptop to run both of these scripts, I don't have an actual server in real life
Python Version: 3.8
OS: Windows 10
Editor: PyCharm Community Edition
I don't understand what restarting input means...
If you mean to show messages while 'writing messages' in the input then consider learning about threads, and spin off a thread to get messages from the server/client and print to the screen.
The below code does not work, when I keep both socket server and client code in the same script file where I run server in the main thread and the client in a separate thread using start_new_thread
import socket, sys
from thread import *
host = socket.gethostname()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((host, 8888))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
s.listen(10)
def clientthread(conn):
conn.send('Welcome to the server. Type something and hit enter\n')
while True:
data = conn.recv(1024)
reply = 'OK...' + data
if not data:
break
conn.sendall(reply)
conn.close()
while 1:
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
start_new_thread(clientthread ,(conn,))
s.close()
If you bind() to your gethostname(), you also have to connect to that interface from the client, even if it is on the same computer. "localhost" or "127.0.0.1" will not work. If you want them to work, either bind() to them directly, or bind to everything ("0.0.0.0" or just an empty string, "").
Low-budget test code:
from _thread import *
import socket,time
def client():
print("Thread starts")
time.sleep(1)
print("Thread connects")
sock=socket.create_connection((socket.gethostname(),8888))
#sock=socket.create_connection(("localhost",8888))
print("Thread after connect")
sock.sendall(b"Hello from client")
sock.close()
print("Thread ends")
serv=socket.socket()
serv.bind((socket.gethostname(),8888))
#serv.bind(("localhost",8888))
#serv.bind(("0.0.0.0",8888))
#serv.bind(("",8888))
serv.listen(10)
start_new_thread(client,())
print("Before accept")
s,c=serv.accept()
print("After accept "+c[0])
print("Message: "+s.recv(1024).decode("ASCII"))
s.close()
serv.close()
Feel free to experiment with testing the various sock+bind combinations.
Here is a snippet from a specific server program I a working on.
Requirements:
I want the program to initiate a socket on port defined by ownport variable and listen on that port for incoming TCP messages.
Based on the specific value I receive on the socket from remote hosts, the server has to initiate functions func1() or func2() [Example: if the value is JOIN, then execute func1 and if it is UPDATE execute func2]
These actions are mutually exclusive and multiple clients may be connected to the server at the same time and might be sending requests.
How can I effectively multithread this so that the server constantly listen on the port and initiate the functions based on the incoming requests in realtime?
# Creating a socket
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
sys.exit();
print "Socket created!"
#Binding the socket to specified ports
try:
sock.bind((ownhost, ownport))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
# Listening for incoming requests
sock.listen(10)
print 'Socket now listening'
conn, addr = sock.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
# Handling the incoming requests received
req = conn.recv(1024)
reqpro = req.split('|')
# If the request is a join request
if reqpro[0] == "JOIN":
func1(reqpro, arg2)
elif (reqpro[0] == 'UPDATE') and (reqpro[1] == 'PRED'):
func2(reqpro,arg2)
else:
print "invalid request type"
sys.exit()
I have the below code and it receives the data I want, how I want, then terminates. How can I set this to connect to my client that always has the same IP and remain connected or listening from that client?
Its a barcode scanner and sends the data fine i just need to be always listing for it.
Servercode.py
import socket #for sockets
import sys #for exit
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM,)
except socket.error as err_msg:
print ('Unable to instantiate socket. Error code: ' + str(err_msg[0]) + ' , Error message : ' + err_msg[1])
sys.exit();
print ('Socket Initialized')
host = socket.gethostname()
port = 12345
s.bind((host, port))
s.listen(5)
print ('listening....')
conn, addr = s.accept()
print ('Got connection from', addr)
while 1:
data = conn.recv(1024)
stringdata = data.decode('ascii')
if not data: break
print ('received data:', stringdata)
conn.close()
You want to reject connections from IP addresses other than a specific one.
You already have most of what you need:
print ('Got connection from', addr)
Just add something like this:
if addr[0] != '192.168.1.200':
conn.close()
I have a server program that can maintain connection with multiple clients. I want to be able to close the socket in response to the message CLOSE by client, or for some other reason. The problem is that the server is stuck on the accept() method and does not care if I close the socket in some other place.
I can use some flag in the main server while, and close the socket after this while, however that means I will have to connect to the server myself after the client request, in order for the while condition to be checked, which smells like really terrible programming.
The code:
import socket
import sys
from thread import *
HOST = '' # Symbolic name meaning all available interfaces
PORT = 9992 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#Function for handling connections. This will be used to create threads
def clientthread(conn):
#Sending message to connected client
conn.send('Welcome to the server. Type something and hit enter\r\n') #send only takes string
data=''
#infinite loop so that function do not terminate and thread do not end.
while True:
#Receiving from client
data += conn.recv(1024)
print data
if data == 'CLOSE':
global s
conn.sendall('You have requested to destroy the connection...')
conn.close()
s.close()
return
if data.find('\n') != -1:
conn.sendall('OK...' + data + '\r\n')
data=''
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
try:
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
start_new_thread(clientthread ,(conn,))
except:
print 'socket issue sorry'
break