Sockets server and client in the same python script - python

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.

Related

Python Socket Return Ping Answer to Client

I'm struggling with getting reply back to client when pinging through socket server.
Trying to create something simple, where I can ping servers from client through socket server.
Client checks that socket server is online, socket server in "server" will respond status. Client sends the ping command to socket server, socket server initiate the ping to where ever. Raw printout will be sent to client.
What's the best way to do it?
First time working with sockets.
Server
#!/usr/bin/python3
import socket
import sys
HOST = '127.0.0.1'
PORT = 8085
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
# Bind socket
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')
# Talk with client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print('Connected')
while True:
dataFromClient = conn.recv(1024)
print(dataFromClient.decode('utf-8'))
if not dataFromClient:
print("[Client] Disconnected")
break
conn.sendall(dataFromClient)
s.close()
Client
#!/usr/bin/python3
import socket
import subprocess
import os
SERVER = "127.0.0.1"
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientSocket.connect((SERVER,8085))
os.system("clear")
os.system("cls")
while True:
data = input("Input: ")
clientSocket.send(data.encode())
# dataFromServer = clientSocket.recv(1024)
# print(dataFromServer.decode())
if data == "ping":
input1 = str(input("Enter command: "))
with subprocess.Popen(input1,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
for line in proc.stdout:
clientSocket.send(line)
print(proc.communicate())
elif data == "help":
print("Command: pingdl,destip=<isp>,repeat=<amount>")
clientSocket.close()

How to effectively multi-thread functions based on data received from a socket in python?

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()

Problems getting telnet to connect to a python socket server

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

How to close a connection of a client when multiple clients are connected?

I am having a multi-client server which listens to multiple clients. Now if to one server 5 clients are connected and I want to close the connection between the server and just one client then how am I going to do that.
My server code is:
import socket
import sys
from thread import *
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
except socket.error,msg:
print "Socket Creation Error"
sys.exit();
print 'Socket Created'
host = ''
port = 65532
try:
s.bind((host, port))
except socket.error,msg:
print "Bind Failed";
sys.exit()
print "Socket bind complete"
s.listen(10)
print "Socket now listening"
def clientthread(conn):
i=0
while True:
data = conn.recv(1024)
reply = 'OK...' + data
conn.send(reply)
print data
while True:
conn, addr = s.accept()
start_new_thread(clientthread,(conn,))
conn.close()
s.close()

Where is the right place to close a server socket (Python)

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

Categories

Resources