How to differentiate between two different socket connections to the same IP? - python-3.x

I have a question. If your socket program is already connected to a user suppose like 192.168.0.25:4545 and in the middle of communication if I run a connect((host,port)) to that ip and port it still accepts the connection.So, is it possible to make something that would connect to the server if a prior connection to that server doesn't already exist. I tried using the router assigned port cuz its unique for each connection, but its getting overly complicated if I do it that way.
Here is the Code dealing with this question
if __name__ == "__main__":
HOST, PORT = "192.168.0.25", 4545
counter_check = 1
while True:
try:
time.sleep(8)
s = Client(HOST, PORT)
s.enable_attempt_reconnect()
if counter_check == 1:
proc = multiprocessing.Process(target=s.start_code)
proc.start() #starting the thread for reverse shell
counter_check += 1
elif proc.is_alive():
proc.terminate() #forcefully close the previous thread
proc = multiprocessing.Process(target=s.start_code)
proc.start() #start a new thread
except Exception:
continue
enable_attempt_reconnect()
def enable_attempt_reconnect(self):
while True:
time.sleep(3)
try:
self.soc.connect((self.host, self.port))
break
except Exception:
continue
Esentially what I am trying to do is if the connection from the client is lost, the client is actively looking for other ways to connect to the server, if another connection comes up, its probably because the current connection one was disconnected, so the client would would proc.terminate() the inital connection and start a newer connection.

Related

ZeroMQ permanent PULL socket

I’ve been using a PUSH/PULL pattern in an application and it works as expected except when I switch off abruptly the computer or remove the ethernet cable in the PULL-side.
The PUSH-side keeps working with other PULL-sockets, but maintains switched off socket as if still were alive.
I have modified TCP-parameters (interval, count...) without results.
Is it possible to avoid this connection even when the host computer is switched off or the ethernet cable removed?
EDIT:
This is a small test i've made
server.py
import zmq
import time
context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.setsockopt(zmq.RCVHWM, 1)
socket.setsockopt(zmq.SNDHWM, 1)
socket.setsockopt(zmq.LINGER, 0)
socket.setsockopt(zmq.IMMEDIATE, 1)
print(socket.sndtimeo)
socket.sndtimeo = 0
socket.setsockopt(zmq.TCP_KEEPALIVE,1)
socket.setsockopt(zmq.TCP_KEEPALIVE_CNT,1)
socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE,1)
socket.setsockopt(zmq.TCP_KEEPALIVE_INTVL,1)
socket.bind('tcp://*:5555')
count= 0
while True:
print('Sending', count)
try:
socket.send(str(count).encode('utf-8'), zmq.NOBLOCK)
count+= 1
print('Ok')
except zmq.error.Again:
print('Error')
time.sleep(0.1)
client.py
import zmq
import time
import sys
#from common import time_utils
context = zmq.Context()
socket = context.socket(zmq.PULL)
server = '127.0.0.1:5555'
try:
server = sys.argv[1]
except IndexError:
pass
socket.setsockopt(zmq.TCP_KEEPALIVE,1)
socket.setsockopt(zmq.TCP_KEEPALIVE_CNT,1)
socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE,1)
socket.setsockopt(zmq.TCP_KEEPALIVE_INTVL,1)
socket.setsockopt(zmq.RCVHWM, 1)
socket.connect(server)
while True:
# Wait for next request from client
message = socket.recv()
print("Received request: ", message)
Running one instance of the server and 2 clients (one in the same machine that runs the server and one in other computer). Removing the ethernet cable of the second computer results in that the server keeps sending messages to the second client for a while.
As you can see I have tested all setsockopt.
Q : Is it possible to avoid this connection even when the host Computer is switched off?
For connection-oriented transport-classes, you may .setsockopt( zmq.IMMEDIATE, 1 ) so as to avoid storing outgoing messages on the PUSH-side for a dead connection.
As an additional step, one may add another, explicit ACK/NACK signalling-flow, that may help independently and explicitly detect any such event of a dead-man not responding on the ACK/NACK-loop(s).
Try using the ZMTP ping/pong options. These should detect the connection being lost as it runs at a higher level than the TCP sockets (which can be held open after the connection is down)
ZMQ_HEARTBEAT_IVL, ZMQ_HEARTBEAT_TIMEOUT and ZMQ_HEARTBEAT_TTL
http://api.zeromq.org/4-3:zmq-setsockopt

Python chat clients not updating

I am working on a GUI based chat program.
I am using someone else's server which has worked well for many people so I am assuming the problem is with my client's code.
When I run a single instance of the client it works perfectly, but if I run two instances of the client on the same computer the listener stops responding when the 2nd client logs in.
# server is from socket module
# chat_box is a tkinter ListBox
# both are copies of global variable
class listener_thread(threading.Thread):
def __init__(self, server, chat_box):
super(listener_thread, self).__init__()
self.server = server
self.chat_box = chat_box
def run(self):
try:
update = self.server.recv(1024)
msg = update.decode("utf-8")
if msg != "":
self.chat_box.insert(END, msg)
except Exception as e:
print(e)
I've verified that the server is putting each client on a different port. The server is receiving the messages. When 'Michael' logs in and says 'Hi' it updates in his chat_box.
Though, the clients are no longer updating their histories after 'Dave' logs in.
Yet, the server continues to show that it is receiving the messages from both clients.
#This is the server output
#Hi is Michael
#Yo is Dave
#So Michael is still connecting and transmitting after Dave connects
Michael - ('127.0.0.1', 56263) connected
Hi
Dave - ('127.0.0.1', 56264) connected
Yo
Hi
The network connection is working properly. It just locks up the list_box updating threads.
No exceptions are being thrown.
I solved my own problem.
I needed to make the chat_history_listbox as a ListBox initially, instead of None
I needed to put the receive code into a function, with a loop and an exit condition
def receive_func():
global server, chat_history_listbox
while True:
try:
update = server.recv(1024)
except OSError as e:
update = None
break
connect()
msg = update.decode("utf-8")
if msg != "":
chat_history_listbox.insert(END, msg)
I needed to make the thread call a function and make it a daemon
listener = Thread(target=receive_func, daemon=True)
listener.start()
This got it working with multiple clients

How do I properly close a socket if I need to reuse the same port?

I created a server program and a client program in which my goal is for the client to send the server TCP packets. In my case, the client is given the IP address of the server and the port to where the packet should be sent. If I run the server code the first time for a specific port, the server program will search for a response. If I run it twice or more, I get the error "address already in use". It seems as if the socket is not properly closing.
As shown in my code, I have tried sock.shutdown() and sock.close() at the end of my program to no avail. I have also tried adding connection.close() and sock.setsockopt() however, I believe I may be confusing Python 2 with Python 3 syntax. (I am using Python 3) Adding or removing these methods results in the same error. I have posted the server code below for reference.
import socket
# TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
server_address = ('10.0.2.6', 2104)
print('Starting up {} port {}'.format(*server_address))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Allows address to be reused
sock.bind(server_address)
# Listen for incoming connections, looking for one connection.
sock.listen(1) # The number of queried connections.
while True:
# Wait for a connection
print('waiting for a connection')
connection, client_address = sock.accept()
try:
print('connection from', client_address)
# Receive the data in small chunks and then send back
while True:
data = connection.recv(90)
print('received {!r}'.format(data))
if data:
print('sending data back to the client')
connection.sendall(data)
break
else:
print('no data from', client_address)
break
finally:
print("Closing current connection") # Cleans up the connection
connection.close()
sock.shutdown(socket.SOCK_STREAM, socket.AF_NET)
sock.shutdown(1)
sock.close()
I expect the program to continue to listen on the same part with multiple executions. However, running this code once gives me the error
socket.error: [Errno 98] Address already in use.

python client recv only reciving on exit inside BGE

using python 3, I'm trying to send a file from a server to a client as soon as the client connects to the server, problem is that the client do only continue from recv when I close it (when the connection is closed)
I'm running the client in blender game engine, the client is running until it gets to recv, then it just stops, until i exit the game engine, then I can see that the console is receiving the bytes expected.
from other threads I have read that this might be bco the recv never gets an end, that's why I added "\n\r" to the end of my bytearray that the server is sending. but still, the client just stops at recv until I exit the application.
in the code below I'm only sending the first 6 bytes, these are to tell the client the size of the file. after this i intend to send data of the file on the same connection.
what am I doing wrong here?
client:
import socket
import threading
def TcpConnection():
TCPsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
TCPsocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
server_address = ('localhost', 1338)
TCPsocket.connect(server_address)
print("TCP Socket open!, starting thread!")
ServerResponse = threading.Thread(target=TcpReciveMessageThread,args=(TCPsocket,))
ServerResponse.daemon = True
ServerResponse.start()
def TcpReciveMessageThread(Sock):
print("Tcp thread running!")
size = Sock.recv(6)#Sock.MSG_WAITALL
print("Recived data", size)
Sock.close()
Server:
import threading
import socket
import os
def StartTcpSocket():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 1338))
server_socket.listen(10)
while 1:
connection, client_address = server_socket.accept()
Response = threading.Thread(target=StartTcpClientThread,args=(connection,))
Response.daemon = True # thread dies when main thread (only non-daemon thread) exits.
Response.start()
def StartTcpClientThread(socket):
print("Sending data")
length = 42
l1 = ToByts(length)
socket.send(l1)
#loop that sends the file goes here
print("Data sent")
#socket.close()
def ToByts(Size):
byt_res = (Size).to_bytes(4,byteorder='big')
result = bytearray()
for r in byt_res:
result.append(r)
t = bytearray("\r\n","utf-8")
for b in t:
result.append(b)
return result
MessageListener = threading.Thread(target=StartTcpSocket)
MessageListener.daemon = True # thread dies when main thread (only non-daemon thread) exits.
MessageListener.start()
while 1:
pass
if the problem is that the client don't find a end of the stream, then how can solve this without closing the connection, as I intend to send the file on the same connection.
Update #1:
to clarify, the print in the client that say "recived" is printed first when I exit the ge (the client is closing). The loop that sends the file and recives it where left out of the question as they are not the problem. the problem still occurs without them, client freeze at recv until it is closed.
Update #2:
here are a image of what my consoles are printing when i run the server and client:
as you can see it is never printing the "Recived" print
when i exit the blender game engine, I get this output:
now, when the engine and the server script is exited/closed/finished i get the data printed. so recv is probably pausing the thread until the socket is closed, why are it doing this? and how can i get my data (and the print) before the socket is closing? This also happens if I set
ServerResponse.daemon = False
here are a .blend (on mediafire) of the client, the server running on python 3 (pypy). I'm using blender 2.78a
Update #3:
I tested and verified that the problem is the same on windows 10 and linux mint. I also made a Video showing the problem:
In the video you can see how I only receive data from the server when i exit blender ge. After some research I besinning to suspect that the problem is related to python threading not playing well with the bge.
https://www.youtube.com/watch?v=T5l9YGIoDYA
I have observed a similar phenomenon. It appears that the Python instance doesn't receive any execution cycles from Blender Game Engine (BGE) unless a controller gets invoked.
A simple solution is:
Add another Always sensor that is fired on every logic tick.
Add another Python controller that does nothing, a no-op.
Hook the sensor to the controller.
I applied this to your .blend as shown in the following screen capture.
I tested it by running your server and it seems to work OK.
Cheers, Jim

python 3.3 socket relay, server can't access value

I'm trying to learn python. One of the main things I'm trying to do is create a relay that will relay sockets sent from one client to another. As I'm beginning this, I've started doing some simple modifications to a basic client/server sample script. However, what occurs is that the server itself will not or for some reason cannot print out the value that it is repeating back to the client. I only get "Recieved ''" like it's an empty string. Please help me understand and fix this?
server program
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
data = ''
message = ''
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
print('Received', repr(data.decode()))
client program
import socket
HOST = '192.168.56.1' # The remote host
PORT = 50007 # The same port as used by the server
x = input('Message:')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(x.encode())
data = s.recv(1024)
s.close()
print('Received', repr(data.decode()))
Good job, Stack Overflow. Now I at least know where I'm not going to find help. That is in itself helpful in some way. The one question that doesn't get deleted goes unanswered for days. lol. If anybody happens to stumble across this thread having this or a similar issue before some presumptuous, self-important chutzpah who probably enjoys the sweet, sweet smell of their own believed to be flawless fart deletes it, I suggest you find a real forum.

Resources