How to access socket for multiple reception using thread - python-3.x

Hello I am new in networking field and using socket in Python
I am trying to access the function frame_reception_function() but I am getting error "OSError: [Errno 98] Address already in use"
In forward_send_received(), I am calling four different functions using thread, because in my work, this node can be received request frame form previous node and also need to forward this frame to next node and it is also receiving data frame form next node and send to the previous node. so it received two from two sides. How it is possible to access the same socket. I am also closing the connection but it does not work.
Can anybody help me to remove the above error (Address already in Used)
def frame_reception_function ():
print ("starting of frame reception")
PORT = 12345
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(('',PORT))
s.listen(1)
conn,address=s.accept()
message=conn.recv(1024).decode()
conn.close()
recv_message=message.split(';')
message_type=recv_message[0]
if (received_message=='req_status'):
print ('Received Message is req_status')
previous_ip=recv_message[1]
return message_type,previous_ip,recv_message
else:
print ("received message is :",received_message)
print ("Received from:",recv_message[4])
ip=recv_message[4]
#cmd = "arp -n " + str(ip) + " | awk '/" + str(ip) + "/{print $3}'" # Can we extract MAC address from IP instead of Broadcast address???
#x = os.popen(cmd).read().strip()
return recv_message[0],ip,recv_message
def forward_send_received():
Frame_type,ip_address,received_message=frame_reception_function ()
print ("after while")
print (Frame_type)
print (Frame_SrcAddr)
print (ip_address)
print (received_message)
if (Frame_type=="req_status"):
if (not Req_Frame_Relayed): # Check Req_Frame_status
forward_req_status_frame()
Req_Frame_Relayed=True
Probabilistic_Reliable_Broadcast(Frame_type)
Send_Data_status_frame()
Probabilistic_Reliable_Broadcast("current_node_data")
else:
if (Frame_SrcAddr not in Resp_forwarded_set):
Resp_forwarded_set()
forward_Data_status_frame(received_message)
Resp_number=Resp_number+1
Probabilistic_Reliable_Broadcast(Frame_type)
while (time.time()-start_time<Status_collecting_time_interval) and (Resp_number<Nmax):
print ("starting of while ")
Thread(target=forward_send_received).start()

Related

how do i make my server able to read data which is sent by client

here i am making server
my_selector = selectors.DefaultSelector()
keep_running = True
server_address = ('localhost', 1040)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(False)
sock.bind(server_address)
sock.listen(5)
my_selector.register(sock, selectors.EVENT_READ, data=None)
this accept function make new connection
def accept(sock):
# print("Accept Function")
new_connection, addr = sock.accept()
print("Connection established.......")
new_connection.setblocking(False)
my_selector.register(new_connection, selectors.EVENT_READ | selectors.EVENT_WRITE, data=None)
this read function reads data sent by client
def read(connection, mask):
global keep_running
print("Read Function")
if mask & selectors.EVENT_READ:
recv_data = connection.recv(1024)
if recv_data:
print("Message received ", recv_data.decode("utf-8"))
else:
print("Message not received")
my_selector.unregister(connection)
connection.close()
keep_running = False
this loop controls my server
while keep_running:
for key, mask in my_selector.select(timeout=None):
if key.data is None:
accept(key.fileobj)
else:
read(key, mask)
my_selector.close()
my question is when server and client run if server gets a new client it control goes to accept function
or if server gets data it goes to read function this programme shows error
client programme does not show any error client programme only send data
please tell me how to fix this error and i am working on windows 10
Error----OSError: [WinError 10022] An invalid argument was supplied
Try looking at this post maybe it helps you :)
The first answer on that where the guy is having the same error says:
Bind the socket before calling connection.recvfrom(65536) using connection.bind((YOUR_IP, PORT)).
OSError: [WinError 10022] An invalid argument was supplied - Windows 10 Python

My if & elif not working on sockets (python 3)

I tried to create a server that receives commands from the client
And to identify which command the client wrote I used if & elif
But when I run the program and write a command from the client, only the first command works (the command on the if) and if I try another command (from elif & else)
The system just doesn't respond (like she's waiting for something)
The Server Code:
import socket
import time
import random as rd
soc = socket.socket()
soc.bind(("127.0.0.1", 7777))
soc.listen(5)
(client_socket, address) = soc.accept()
if(client_socket.recv(4) == b"TIME"):
client_socket.send(time.ctime().encode())
elif(client_socket.recv(4) == b"NAME"):
client_socket.send(b"My name is Test Server!")
elif(client_socket.recv(4) == b"RAND"):
client_socket.send(str(rd.randint(1,10)).encode())
elif(client_socket.recv(4) == b"EXIT"):
client_socket.close()
else:
client_socket.send(b"I don't know what your command means")
soc.close()
The Client Code:
import socket
soc = socket.socket()
soc.connect(("127.0.0.1", 7777))
client_command_to_the_server = input("""
These are the options you can request from the server:
TIME --> Get the current time
NAME --> Get the sevrer name
RAND --> Get a Random int
EXIT --> Stop the connect with the server
""").encode()
soc.send(client_command_to_the_server)
print(soc.recv(1024))
soc.close()
if(client_socket.recv(4) == b"TIME"):
client_socket.send(time.ctime().encode())
This will check the first 4 byte received from the server
elif(client_socket.recv(4) == b"NAME"):
client_socket.send(b"My name is Test Server!")
This will check the next 4 bytes received from the server. Contrary to what you assume it will not check the first bytes again since you called recv to read more bytes. If there are no more bytes (likely, since the first 4 bytes are already read) it will simply wait. Instead of calling recv for each comparison you should call recv once and then compare the result against the various strings.
Apart from that: recv will only return up to the given number of bytes. It might also return less.

I want to exception of linux command

I want to control on python
try catch wifi list and connect to catching wife name and password
but I use linux command so I can't care linux error window
I want to check password in python
when i set wrong password, open Network manager.
What should i do?
import commands
def space_filter(x):
if x == ' ':
pass
else:
return x
#fail, output = commands.getstatusoutput("nmcli dev wifi list")
test= commands.getoutput("nmcli dev wifi list")
test1=test.split(' ')
print test
print test1
test2 = []
test1 = list(filter(space_filter, test1))
#print test1
for x in range(len(test1)):
if test1[x] == '\n*' or test1[x] =='\n':
test2.append(test1[x+1])
#print test2
try:
result = commands.getoutput("nmcli d wifi connect " + test2[0] + " password 1234")
print result
except:
print "password is wrong"[enter image description here][1]
Exceptions are a language specific construct to catch abnormal/error situations. The correct way to check error conditions in shell commands is the return value.
Use the getstatusoutput function in commands module to catch the return value along with the output. In your case, you would need to parse the output along with the return code to get the reason for failure since nmcli only distinguishes between certain kinds of failure. - https://developer.gnome.org/NetworkManager/stable/nmcli.html
(status, output) = commands. getstatusoutput("nmcli d wifi connect " + test2[0] + " password 1234")
if not status:
print "error"

Python36 and sockets

So I'm connected to an IRC chat using socket.connec
I log in by passing my variables via socket.send
The log in is successful and then I sit in a while true loop using
Socket.recv(1024)
If I just continually print the response everything looks fine, but let's say I want to add to the end of the string... I noticed that socket.recv doesn't always get the full message (only grabs up to 1024 as expected) and the remainder of the message is in the next iteration of the loop.
This makes its it impossible to process the feedback line by line.
Is there a better way to constantly read the data without it getting trunked? Is it possible to figure out the size of the response before receiving it so the buffer can be set dynamically?
TCP is a stream-based protocol. Buffer the bytes received and only extract complete messages from the stream.
For complete lines, look for newline characters in the buffer.
Example server:
import socket
class Client:
def __init__(self,socket):
self.socket = socket
self.buffer = b''
def getline(self):
# if there is no complete line in buffer,
# add to buffer until there is one.
while b'\n' not in self.buffer:
data = self.socket.recv(1024)
if not data:
# socket was closed
return ''
self.buffer += data
# break the buffer on the first newline.
# note: partition(n) return "left of n","n","right of n"
line,newline,self.buffer = self.buffer.partition(b'\n')
return line + newline
srv = socket.socket()
srv.bind(('',5000))
srv.listen(1)
conn,where = srv.accept()
client = Client(conn)
print(f'Client connected on {where}')
while True:
line = client.getline()
if not line:
break
print(line)
Example client:
s=socket()
s.connect(('127.0.0.1',5000))
s.sendall(b'line one\nline two\nline three\nincomplete')
s.close()
Output on server:
Client connected on ('127.0.0.1', 2667)
b'line one\n'
b'line two\n'
b'line three\n'

Simultaneous input and output for network based messaging program

In python, I am creating a message system where a client and server can send messages back and forth simeltaneously. Here is my code for the client:
import threading
import socket
# Global variables
host = input("Server: ")
port = 9000
buff = 1024
# Create socket instance
s = socket.socket()
# Connect to server
s.connect( (host, port) )
print("Connected to server\n")
class Recieve(threading.Thread):
def run(self):
while True: # Recieve loop
r_msg = s.recv(buff).decode()
print("\nServer: " + r_msg)
recieve_thread = Recieve()
recieve_thread.start()
while True: # Send loop
s_msg = input("Send message: ")
if s_msg.lower() == 'q': # Quit option
break
s.send( s_msg.encode() )
s.close()
I have a thread in the background to check for server messages and a looping input to send messages to the server. The problem arises when the server sends a message and the user input is immediately bounced up to make room for the servers message. I want it so that the input stays pinned to the bottom of the shell window, while the output is printed from the 2nd line up, leaving the first line alone. I have been told that you can use curses or Queues to do this, but I am not sure which one would be best in my situation nor how to implement these modules into my project.
Any help would be appreciated. Thank you.
I want it so that the input stays pinned to the bottom of the shell
window, while the output is printed from the 2nd line up, leaving the
first line alone. I have been told that you can use curses
Here's a supplemented version of your client code using curses.
import threading
import socket
# Global variables
host = input("Server: ")
port = 9000
buff = 1024
# Create socket instance
s = socket.socket()
# Connect to server
s.connect( (host, port) )
print("Connected to server\n")
import sys
write = sys.stdout.buffer.raw.write
from curses import *
setupterm()
lines = tigetnum('lines')
change_scroll_region = tigetstr('csr')
cursor_up = tigetstr('cuu1')
restore_cursor = tigetstr('rc')
save_cursor = tigetstr('sc')
def pin(input_lines): # protect input_lines at the bottom from scrolling
write(save_cursor + \
tparm(change_scroll_region, 0, lines-1-input_lines) + \
restore_cursor)
pin(1)
class Recieve(threading.Thread):
def run(self):
while True: # Recieve loop
r_msg = s.recv(buff).decode()
write(save_cursor+cursor_up)
print("\nServer: " + r_msg)
write(restore_cursor)
recieve_thread = Recieve()
recieve_thread.daemon = True
recieve_thread.start()
while True: # Send loop
s_msg = input("Send message: ")
if s_msg.lower() == 'q': # Quit option
break
s.send( s_msg.encode() )
pin(0)
s.close()
It changes the scrolling region to leave out the screen's bottom line, enters the scrolling region temporarily to output the server messages, and changes it back at the end.

Resources