how to refuse socket connection for a Specific IP in Python? - python

listenr code :
import socket
host = socket.gethostbyname(socket.gethostname())
port = int(raw_input("PORT > "))
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(5)
while True:
c, addr = server.accept()
buff = 2048
print addr[0]+" connected."
c.send("Connection Established")
data = c.recv(buff)
if data:
print data
client code:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname(socket.gethostname())
port = int(raw_input("PORT > "))
server.connect((host, port))
buff = 2048
data = server.recv(buff)
if data:
print data
and is it possible to receive data from client and listen on port at the same time ? how?

After accept() use thread to send/receive data to/from client and at the same time main thread can wait for next client running accept() again. It is standard method .

Related

Can't get client to connect to server

I'm just very confused still about the basic socket process. Tried multiple ways to try and get the socket to connect but it keeps refusing.
client code- socket_client.py
import socket
host = socket.gethostname()
port = 8080
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host,port))
res = client.send (b' testing data send...')
client.close()
server code- server_client.py
import socket
host = socket.gethostname()
port = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(10)
x=0
server_data = []
while True:
conn, addr = server.accept()
data = conn.recv(4096).decode()
x += 1
print ('Servicing client at %s'%addr[0])
server_data = client.recv(4096)
client_close()
server.close()
You have some problems in your server. You read from the connection but never use it, and you do client.recv when there is no variable client. This works:
import socket
host = socket.gethostname()
port = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(10)
x=0
server_data = []
while True:
conn, addr = server.accept()
x += 1
print ('Servicing client at %s'%addr[0])
data = conn.recv(4096).decode()
print( "Received", data )
conn.close()
server.close()
Do remember that Python has a SocketServer module that can make some of this easier. If you need to get fancier, there are few modules better than Twisted at this kind of thing.
ALSO remember that the server must be running before you start the client. Someone has to be listening, otherwise the connection is rejected.

How to give SSL encryption to a python chat program?

I made a little chat program, and I'm using in to chat with a friend over WAN.
We are now worried about security: our program just uses socket module to send byte encoded strings.
How would this appear to an interceptor?
How could I use a SSL connection between us two to make our messaging secured?
Will SSL be enough to make our chat 100% private?
Thank you
Also, here is our chat's code:
Server-side:
import socket
HOST = my ip here
PORT = 1234
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORTA))
print('Listening')
s.listen()
conn, addr = s.accept()
with conn:
print('Connected to', addr)
conn.sendall(b'')
while True:
data = conn.recv(1024).decode('utf-8')
print(data)
risp = input('Message: ').encode('utf-8')
conn.sendall(risp)
if not data:
print('Not receiving')
break
client side:
import socket
HOST = 'my ip' # The server's hostname or IP address
PORT = 1234 # The port used by the server
something = ''
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
while something!= 'esc'.encode('utf-8'):
something= input('Your messagge:').encode('utf-8')
s.sendall(something)
data = s.recv(1024)
print(data.decode('utf-8'))
print('Received: ', repr(data))

Show all the clients connected to a socket server and send them data

I have this simple code:
import socket
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind((host, port))
socket.listen()
while True:
client_socket, addr = socket.accept()
send = input("Send: ") # but I need a way to send it to all the clients connected
if send == "devices":
# here I'd have a list of all devices connected
client_socket.send(send.encode())
data = client_socket.recv(4096)
print (data)
As I wrote in the comments, I need a way to manage them all in one. How can I do? Maybe with _thread library?
You could mainitain a list of clients that can be passed to an external function that performs an action on all clients.
import socket
host = ''
port = 1000
max_connections = 5
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind((host, port))
socket.listen(max_connections)
clients = [] # Maintain a list of clients
try:
while True:
client_socket, addr = socket.accept()
clients.append(client_socket) #Add client to list on connection
i_manage_clients(clients) #Call external function whenever necessary
except KeyboardInterrupt:
socket.close()
def i_manage_clients(clients): #Function to manage clients
for client in clients:
client.send('Message to pass')
The above example demonstrates how send data to all clients at once. You could use the
import socket
from thread import *
host = ''
port = 1000
max_connections = 5
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind((host, port))
socket.listen(max_connections)
try:
while True:
client_socket, addr = socket.accept()
start_new_thread(i_manage_client, (client_socket,addr))
except KeyboardInterrupt:
socket.close()
def i_manage_client(client_socket, addr): #Function to manage clients
client_socket.send('Message to pass')
data = client_socket.recv(4096)
print(client_socket)
print(addr)
print(data)

How to connect to server, listen for arbitrary time and send back data

I'm trying to:
Connect to a server/port
Listen for x seconds
Receive user input
Send user input to server
Go back to step 2
So far, I've written the following code, but it's not working properly receiving input after the first send. Any help would be greatly appreciated.
import socket
import select
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('domain.com', 1234))
client_socket.setblocking(0)
timeout = 5
while True:
while True:
ready = select.select([client_socket], [], [], timeout)
if ready[0]:
data = client_socket.recv(4096)
print data
else:
break
data = raw_input("Enter input:")
client_socket.send(data)
You need to have separate server side code and client side code. This article has been referred.
Server binds to a port and listens for clients
server.py
import select
import socket
# Create a TCP/IP socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
# Bind the socket to the port
server_address = ('localhost', 1234)
server.bind(server_address)
# Listen for incoming connections
server.listen(5)
# Sockets from which we expect to read
inputs = [ server ]
# Sockets to which we expect to write
outputs = [ ]
while inputs:
readable, writable, exceptional = select.select(inputs, outputs, inputs)
# Handle inputs
for s in readable:
if s is server:
# A "readable" server socket is ready to accept a connection
connection, client_address = s.accept()
connection.setblocking(0)
inputs.append(connection)
else:
data = s.recv(1024)
if data:
print "Receiving data from client"
print data
else:
inputs.remove(s)
s.close()
Client first establishes a connection with the server and then keeps on sending user input to the server.
client.py
import socket
server_address = ('domain.com', 1234)
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(server_address)
while True:
data = raw_input("Enter input:")
sock.send(data)
Open terminal.
Run server in background:
python server.py &
Run client after that:
python client.py

Change the socket port of a server that is already running (python)

I have a server written in python 2.7 that executes an infinite loop and process information from port 5000. Is it possible to change this connection port without restarting the server?
For example: the server is running in port 5000 and receives a 'change_port' option, the server module has to stop listening in port 5000 to start listening in port 7000. I don't know if i can manipulate sockets like that... Thanks
Once you have bound a socket to an address (interface, port) it cannot be changed. However, you can create a new socket (or many, depending on your needs) and bind it to your address (interface, port).
The code will differ based on the transport layer protocol you're using:
TCP:
# 1) Create first socket
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.bind(('0.0.0.0',5000))
# 2) Create second socket
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.bind(('0.0.0.0',7000))
# 3) Wait for a connection on the first socket
s1.listen(5)
sc, address = s1.accept()
# 4) Once a connection has been established...
# send, recv, process data
# until you need the next socket
# 5) Open connection on second socket
s2.listen(1)
sc2, address2 = s2.accept()
# now it probably a good time to tell the client (via s1) that s2 is ready
# client connects to s2
There you go
UDP (almost the same):
s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s1.bind(('0.0.0.0',5000))
s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s2.bind(('0.0.0.0',7000))
data, addr = s1.recvfrom(256)
s1.sendto("s2 ready",addr)
data2, addr2 = s2.recvfrom(256)
Simplified, but that's all there really is to it.
You might consider verifying that the address of the client from s1 is the same as the client connecting to s2.
No, it seems that you cannot run the socket.bind() method when its already bound. However, I have a solution you can use with the Asyncore module.
Heres my server:
import asyncore
import socket
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
data = self.recv(8192)
if data:
print "Recieved Data: ", data, ". This server address:", self.getsockname()
class EchoServer(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(5)
def handle_accept(self):
pair = self.accept()
if pair is not None:
sock, addr = pair
print 'Incoming connection from %s' % repr(addr)
handler = EchoHandler(sock)
server = EchoServer('localhost', 56787)
server = EchoServer('localhost', 56788)
asyncore.loop()
Here are my clients:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 56787))
data = ""
while data.upper() != "Q":
data = raw_input("Enter something to send to the server")
s.send(data)
s.close()
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 56788))
data = ""
while data.upper() != "Q":
data = raw_input("Enter something to send to the server")
s.send(data)
s.close()
This worked well, the python handled both ports. You should also be able to define seperate server classes for each of your ports.

Categories