hi i create server client model in which client keep checking if new device add or not and send response to server side its working fine what i want to display the response i get from client to server on web browser continuously using flask or Django.
this is my client code
from socket import *
import subprocess, string, time
host = 'localhost' # '127.0.0.1' can also be used
port = 53000
sock = socket()
# Connecting to socket
sock.connect((host, port)) # Connect takes tuple of host and port
def detect_device(previous):
import socket
username2 = socket.gethostname()
ip=socket.gethostbyname(username2)
total = subprocess.run('lsblk | grep disk | wc -l', shell=True, stdout=subprocess.PIPE).stdout
time.sleep(3)
# if conditon if new device add
if total>previous:
response = "Device Added in " + username2 + " " + ip
sock.send(response.encode())
# if no new device add or remove
elif total==previous:
detect_device(previous)
# if device remove
else:
response = "Device Removed in " + username2 + " " + ip
sock.send(response.encode())
# Infinite loop to keep client running.
while True:
data = sock.recv(1024)
if (data == b'Hi'):
while True:
detect_device(subprocess.run(' lsblk | grep disk | wc -l', shell=True , stdout=subprocess.PIPE).stdout)
sock.close()
this is my server side code
from socket import *
# Importing all from thread
import threading
# Defining server address and port
host = 'localhost'
port = 53000
# Creating socket object
sock = socket()
# Binding socket to a address. bind() takes tuple of host and port.
sock.bind((host, port))
# Listening at the address
sock.listen(5) # 5 denotes the number of clients can queue
def clientthread(conn):
# infinite loop so that function do not terminate and thread do not end.
while True:
# Sending message to connected client
conn.send('Hi'.encode()) # send only takes string
data =conn.recv(1024)
print (data.decode())
while True:
# Accepting incoming connections
conn, addr = sock.accept()
# Creating new thread. Calling clientthread function for this function and passing conn as argument.
thread = threading.Thread(target=clientthread, args=(conn,))
thread.start()
conn.close()
sock.close()
this is output on server side
Device Added in wraith 192.168.10.9
Device Removed in wraith 192.168.10.9
i need to display this output on web page .
Flask and Django are Web application frameworks that are designed for the HTTP protocol, but you're using the low-level socket library and basically not using any established protocol. If you want to use Flask/Django because you want to have a broadcasting platform for the results of your device-watching client-side script, then I recommend that instead of socket, use requests (link) in your client script to send an HTTP POST request to your Flask/Django Web app. As for how to build the app, well there are tutorials for that. I do want to note that the minimalist Flask is probably a better fit for this project than the more opinionated Django framework.
Related
in TCP sockets you bind then accept connections by s.accept() but in UDP socket you just bind server and anyone connect (if i am wrong correct me) so how to control the clients like for example if 5 clients connect to the server close the server or if someone connect to the server send him a message saying welcome to the server
Thanks for any answers .
By definition, UDP has no concept of 'sessions', so it won't know how many it is currently handling.
You will need to implement some kind of session management within your code to decide when a client is or is not active, and take action on that.
An example code section which should allow up to five clients and expire them after thirty seconds is below.
bind_ip = '192.168.0.1' ## The IP address to bind to, 0.0.0.0 for all
bind_port = 55555 ## The port to bind to
timeout = 30 ## How long before forgetting a client (seconds)
maximum = 5 ## Maximum number of clients
###
import socket
import time
## Create the socket as an internet (INET) and UDP (DGRAM) socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
## Bind to the server address and port
sock.bind((bind_ip, bind_port))
## Make a dict to store when each client contacted us last
clients = dict()
## Now loop forever
while True:
## Get the data and the address
data, address = sock.recvfrom(1024)
## Check timeout of all of the clients
for addr in clients.keys():
## See if the timeout has passed
if clients[addr] < (time.time() - timeout):
## Expire the client
print('Nothing from ' + addr + ' for a while. Kicking them off.')
clients.pop(addr)
## Check if there are too many clients and if we know this client
if len(clients.keys()) > maximum and address not in clients.keys():
print('There are too many clients connected!')
continue
## Update the last contact time
clients[address] = time.time()
## Do something with the data
print('Received from ' + str(address) + ': ' + str(data))
This is by no means the most efficient way to do this, and serves as an example only.
Related reading: https://en.wikibooks.org/wiki/Communication_Networks/TCP_and_UDP_Protocols/UDP
I want to create a multiprocessing echo server. I am currently using telnet as my client to send messages to my echo server.Currently I can handle one telnet request and it echos the response. I initially, thought I should intialize the pid whenever I create a socket. Is that correct?
How do I allow several clients to connect to my server using multiprocessing.
#!/usr/bin/env python
import socket
import os
from multiprocessing import Process
def create_socket():
# Create socket
sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Port for socket and Host
PORT = 8002
HOST = 'localhost'
# bind the socket to host and port
sockfd.bind((HOST, PORT))
# become a server socket
sockfd.listen(5)
start_socket(sockfd)
def start_socket(sockfd):
while True:
# Establish and accept connections woth client
(clientsocket, address) = sockfd.accept()
# Get the process id.
process_id = os.getpid()
print("Process id:", process_id)
print("Got connection from", address)
# Recieve message from the client
message = clientsocket.recv(2024)
print("Server received: " + message.decode('utf-8'))
reply = ("Server output: " + message.decode('utf-8'))
if not message:
print("Client has been disconnected.....")
break
# Display messags.
clientsocket.sendall(str.encode(reply))
# Close the connection with the client
clientsocket.close()
if __name__ == '__main__':
process = Process(target = create_socket)
process.start()
It's probably a good idea to understand which are blocking system calls and which are not. listen for example is not blocking and accept is blocking one. So basically - you created one process through Process(..), that blocks at the accept and when a connection is made - handles that connection.
Your code should have a structure - something like following (pseudo code)
def handle_connection(accepted_socket):
# do whatever you want with the socket
pass
def server():
# Create socket and listen to it.
sock = socket.socket(....)
sock.bind((HOST, PORT))
sock.listen(5)
while True:
new_client = sock.accept() # blocks here.
# unblocked
client_process = Process(target=handle_connection, args=(new_client))
client_process.start()
I must also mention, while this is a good way to just understand how things can be done, it is not a good idea to start a new process for every connection.
The initial part of setting up the server, binding, listening etc (your create_socket) should be in the master process.
Once you accept and get a socket, you should spawn off a separate process to take care of that connection. In other words, your start_socket should be spawned off in a separate process and should loop forever.
I am trying to connect to a server using python sockets. I am able to make a connection and fetch the response data. However, I want the socket communication to be interactive from the client side.
For instance, if I use netcat to connect to the server, the communication is interactive:
nc aa.bb.cc.dd 1234
Server greets you
I can enter the input here
Server responds to my input
However, when I make the connection using python sockets, all I receive is the greeting from the Server and program completes execution.
Here is the python code I am using:
#! /usr/bin/python
import os
import sys
import socket
host = "aa.bb.cc.dd"
port = 1234
remote_ip = socket.gethostbyname(host)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((remote_ip, port))
print s.recv(1024)
I want to modify the above python program so that I can send inputs to the Server as well.
Thanks.
Usually you do
input_data = input("Enter something: ")
s.send(bytes(input_data,'utf-8'))
You could use a while loop to get user input, send to server, and get a response continuously.
while True:
print(str(s.receive(1024)))
toSend = input()
s.send(bytes(toSend, "utf-8"))
I am new to networking programming and python.
I am trying to figure out how to run different jobs at the server side.
For example, I want one function to create connections for incoming clients but in the same time I can still do some administration work from the terminal.
My code is as below but it doesn't work:
Edited: it doesn't work means it will get stuck in the init_conn() function
Like:
starting up on localhost port 8887
Thread: 0 Connected with 127.0.0.1:48080
# waiting
I am looking into SocketServer framework but don't know how that works.
from thread import *
import socket
def init_conn():
thread_count =0
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
server_address = ('localhost', 8887)
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)
# Listen for incoming connections
sock.listen(10)
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = sock.accept()
print 'Thread: '+ str(thread_count) + ' 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,))
thread_count +=1
sock.close()
def clientthread(conn):
# receive data from client and send back
def console():
print 'this is console'
option = raw_input('-v view clients')
if option == 'v':
print 'you press v'
def main():
start_new_thread( init_conn(),() )
start_new_thread( console(),() )
if __name__ == "__main__":
main()
Your problem is probably that you start the program, sometimes it prints "this is console" and then it ends.
The first bug is that you call the methods instead of passing the handle to start_new_thread. It must be:
start_new_thread( init_conn, () )
i.e. no () after the function name.
The program doesn't do much because start_new_thread() apparent starts a thread and then waits for it to stop. The documentation is pretty unclear. It's better to use the new threading module; See http://pymotw.com/2/threading/
def main():
t = threading.Thread( target=init_conn )
t.daemon = True
t.start()
console()
so the code will run until console() ends.
I suggest to split the server and the command line tool. Create a client which accepts commands from the command line and sends them to the server. That way, you can start the console from anywhere and you can keep the code for the two separate.
Seeing that you're new to python, have you tried taking a look at the threading module that comes with the standard library?
import threading
... #rest of your code
while conditions==True:
i = threading.Thread(target=init_conn)
c = threading.Thread(target=console)
i.start()
c.start()
Can't say I've done too much with networking programming with python, so I don't really have much to say in that manner, but at least this should get you started with adding multithreading to your project.
Using SocketServer you may implement a client/server system. The documentation gives small examples which may be useful for you. Here is an extended example from there:
server.py :
import SocketServer
import os
import logging
FORMAT = '[%(asctime)-15s] %(message)s'
logging.basicConfig(format=FORMAT, level=logging.DEBUG)
class MyServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
# By setting this we allow the server to re-bind to the address by
# setting SO_REUSEADDR, meaning you don't have to wait for
# timeouts when you kill the server and the sockets don't get
# closed down correctly.
allow_reuse_address = True
request_queue_size = 10
def __init__(self, port):
self.host = os.uname()[1]
self.port = port
SocketServer.TCPServer.__init__(self, (self.host,self.port), MyTCPHandler)
logging.info( "Server has been started on {h}:{p}".format(h=self.host,p=self.port) )
class MyTCPHandler(SocketServer.BaseRequestHandler):
"""
The RequestHandler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
# max length is here 1024 chars
self.data = self.request.recv(1024).strip()
logging.info( "received: {d}".format(d=self.data) )
# here you may execute different functions according to the
# request string
# here: just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
PORT = 8887
if __name__ == "__main__":
# Create the server, binding to localhost on port 8887
#server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server = MyServer( PORT )
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
client.py
import socket
import sys
import logging
FORMAT = '[%(asctime)-15s] %(message)s'
logging.basicConfig(format=FORMAT, level=logging.DEBUG)
HOST, PORT = "workstation04", 8887
logging.info( "connect to server {h}:{p}".format(h=HOST,p=PORT ) )
# read command line
data = " ".join(sys.argv[1:])
# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Connect to server and send data
sock.connect((HOST, PORT))
sock.sendall(data + "\n")
# Receive data from the server and shut down
received = sock.recv(1024)
finally:
sock.close()
logging.info( "Sent: {}".format(data) )
logging.info( "Received: {}".format(received) )
The output looks something like:
server side:
> python server.py
[2015-05-28 11:17:49,263] Server has been started on disasterarea:8887
[2015-05-28 11:17:50,972] received: my message
client side:
[2015-05-28 11:17:50,971] connect to server disasterarea:8887
[2015-05-28 11:17:50,972] Sent: my message
[2015-05-28 11:17:50,972] Received: MY MESSAGE
You can run several clients (from different consoles) in parallel. You may implement a request processor on the server side which processes the incoming requests and executes certain functions.
Alternatively, you may use the python module ParallelPython which executes python code locally on a multicore system or on a cluster and clusters. Check the http examples.
I had to force pip to install this module:
pip install --allow-external pp --allow-unverified pp pp
As an exercise, I looked for a simple Python chat client-server system to modify and toy with. The first major failing I found in the system was that it used a single tcp connection for the server and client to communicate. The second was that you could only have two people (one using the client, and the other using the server) communicate. Thirdly, consecutive posts were impossible. One person sent a message, then had to wait for the other person to send a single message before talking again. Very, very limiting.
So I began threading it and experimenting with the sockets. Clients connect to the server once, give their IP addresses, create a listening thread, and then reconnect to the server's message receiver.
All posts are sent to that receiver, which iterates through a list of connected clients and connects to each of them and sends the message (with the sender's name in the beginning; misc feature).
(I know that opening a new connection so often like that is inefficient, but I wanted to keep with tcp connections until I had it working, and THEN go to UDP)
However, weird crap began happening. Suffice it to say that I have nightmares of Error 91.
Could anyone identify how to render this code operable within this structure and feature-set?
(Python version 2.6 yey; ignore the infinite loop that is just a placeholder)
SERVER CODE:
from socket import *
from time import time, ctime
import Queue, threading
IP = ''
PORT = 5000
PORTPlus = 2
PORTRec = 1000
ADS = (IP, PORT)
namelist = []
clientlist = []
class clientRec(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
print "I'm this far:", (IP, (PORT + PORTRec))
self.receiver = socket(AF_INET, SOCK_STREAM)
self.receiver.bind((IP, PORT + PORTRec))
self.sender = socket(AF_INET, SOCK_STREAM)
def run(self):
global clientlist, namelist
self.receiver.listen(10)
connected = True
while connected:
tcpcli, addr = receiver.accept()
message = tcpcli.recv(1024) # Accept clien't IP for home-dialing
for i in range(clientlist.__len__()): # For each connected client
try:
sender.connect(clientlist(i)) # connect
sender.send(namelist[i] + message) # and deliver message with sender's name
sender.close()
except:
del clientlist[i], namelist[i]
print "ADS:", (IP, 5000)
handle = clientRec()
tcpsoc = socket(AF_INET, SOCK_STREAM) # Paperwork
tcpsoc.bind(ADS) # Bind self to port
tcpsoc.listen(5) # Listen on that port0
handle.start() # Start thread
# Main
while 1:
print "Waiting for connection"
tcpcli, addr = tcpsoc.accept() # Accept unknown client
print "Connection received; handling..."
namelist.append(tcpcli.recv(1024)) # Accept client's name
client_IP = tcpcli.recv(1024) # Accept clien't IP for home-dialing
client_port = int(tcpcli.recv(1024))# Accept clien't listening port
port_assign = PORT + PORTRec
tcpcli.send(str(port_assign)) # Tell the client that port
tcpcli.close() # Close client connection
clientlist.append((client_IP, client_port))# Add client to send-list
print "Handled."
tcpsoc.close()
CLIENT CODE:
#!/usr/bin/env python
from socket import *
import threading, cgi, os
IP = ''
PORT = 5000
PORTmy = 100
ADS = (IP, PORT)
class iListen(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.receiver = socket(AF_INET, SOCK_STREAM)# Paperwork
self.receiver.bind(('', PORT + PORTmy)) # Listen on that port
self.receiver.listen(5) # Listen for posts
def run(self):
while listening:
tcpcli, addr = receiver.accept() # Accept unknown client
message = tcpcli.recv(1024)
if message == "/q":
listening = False
tcpcli.close()
# Initial CONNECT
myname = raw_input("Tell me yer name partnah: ")
tcpsoc = socket(AF_INET, SOCK_STREAM)
tcpsoc.connect(ADS) # First Connect
tcpsoc.send(myname) # Declare name
tcpsoc.send(gethostbyname(gethostname()))# Give IP address
tcpsoc.send(str(PORT + PORTmy)) # Give listening port
ADS = (IP, int(tcpsoc.recv(1024))) # Get new connect details
tcpsoc.close() # Close old connection
listen = iListen() # Create listener thread
listen.start() # Start listening
# RECONNECT
print ADS
tcpsoc = socket(AF_INET, SOCK_STREAM)
tcpsoc.connect(ADS) # reconnect to new port
connected = True
# Main Chat-loop
while connected:
mes = raw_input(">>>")
tcpsoc.send(mes)
if mes == "/q":
tcpsoc.close()
connected = False
time.sleep(4)
sys.exit()
I am working on something alot like this, but I am instead going to implement text encryption. I see you are suing lists for the client list... but I would say there is a better way of doing that. I am using a dictionary.
if you are familiar with dictionaries, skip the next paragraph.
Dicionaries can handle basicly 2 variables, and are defined using the {}.
>>> stuff = {'a':'hello','b':'world'}
>>> print stuff['a']
hello
>>> print stuff['a'],stuff['b']
hello world
so using this, you can can make a dictionary like {'username':'ipaddr'} this way you can make it so that both usernames and ips are all in one variable. If you want the end product like me, you will be making it so all the server does is repeat the message, and send it to everyone who is connected. then the server can just cycle through the usernames.
as another note, I think the tcpsoc.listen(5) is how many people can beconnected at once... I think thats what i read somewhere.
I have no idea why you would be having that error, but if you want to look at my halfway constucted code, you are more than welcome too. (ignore the import random, this is not yet used, but will be part of the encryption system)
http://piratepad.net/PwQzdU0bkk