python socket server with arguments - python

Hello so I am making a python socket server and client and I am trying to figure out how I can make it so when the server sends a message to the client using arguments(I am not good with explaining myself) but basically my issue is this
Server Console:
Command: >senddata 127.0.0.1 32
Clients Response:
Command Accepted!
Traceback (most recent call last):
File "C:\Users\Goten\Desktop\client\client.py", line 18, in <module>
ip = sys.argv[1]
IndexError: list index out of range
I am sending 32 bytes of data(I think) to 127.0.0.1 and it wont work
This is my clients code:
import socket
import sys
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "127.0.0.1"
port = 8888
socket.connect((host, port))
while True:
msg = socket.recv(1024)
if ">senddata".lower() in msg:
print("Command Accepted!")
ip = sys.argv[1]
datasize = sys.argv[2]
data = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
port = 80
data.sendto(datasize, (ip, port))
print("Sent")
I seriously cannot figure out what I am doing wrong

You are reading from msg, not sys.argv.
if ">senddata".lower() in msg:
print("Command Accepted!")
ip = msg.split(" ")[1]
datasize = msg.split(" ")[2]

Related

ipv6 python sockets not working ! OSError: [Errno 22] Invalid argument

I have a simple client server program and the server side works but for some reason I can't get the the client to interact to the server. I am able to launch the server and use nc -6 fe80::cbdd:d3da:5194:99be%eth1 2020 and connect to it.
Server code:
#!/usr/bin/env python3
from socket import *
from time import ctime
HOST='::'
PORT = 2020
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET6, SOCK_STREAM)
##tcpSerSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
print('Waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept()
print('...connected from:', addr)
while True:
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
tcpCliSock.send(('[%s] %s'%(bytes(ctime(), 'utf-8'), data)).encode('utf-8'))
tcpCliSock.close()
tcpSerSock.close()
client code:
#!/usr/bin/python3
from socket import *
def tcp_ipv6():
HOST = 'fe80::cbdd:d3da:5194:99be%eth1'
PORT = 2020
ADDR = (HOST, PORT)
BUFSIZ = 1024
sock = socket(AF_INET6, SOCK_STREAM)
sock.connect(ADDR)
while True:
data = input('> ')
if not data:
break
sock.send(data)
response = sock.recv(BUFSIZ)
if not response:
break
print(response.decode('utf-8'))
sock.close()
tcp_ipv6()
When I run the client code I get:
Traceback (most recent call last):
File "client.py", line 44, in <module>
tcp_ipv6()
File "client.py", line 31, in tcp_ipv6
sock.connect(ADDR)
OSError: [Errno 22] Invalid argument
Edit1:
Thanks to Establishing an IPv6 connection using sockets in python
4-tuple for AF_INET6
ADDR = (HOST, PORT, 0, 0)
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0)
sock.connect(ADDR)
Still having the same error
Any idea?
Thanks in advance
Some parts of your question have been asked before.
Establishing an IPv6 connection using sockets in python
However, it is not the entire reason why it is not working correctly. If you look at your IPv6 address. fe80::cbdd:d3da:5194:99be%eth1 You can see the %eth1 at the end. That is not part of the internet address. Change HOST to HOST = 'fe80::cbdd:d3da:5194:99be'. And it should work.
I would also like to point out another error in your code. You are attempting to send a string (received from input) over the socket. However, this method only accepts byte like objects. You can add data = data.encode('utf-8') to fix this.
The higher level function - create_connection , to connect to port works in such case. Sample scriptlet is given as follows. Though why sock.connect fails needs to be identified.
HOST = "xxxx::xxx:xxxx:xxxx:xxxx%en0"
PORT = 2020
ADDR = (HOST, PORT)
BUFSIZ = 1024
sock=create_connection(ADDR)

Making an outbound connection

I've recently been tinkering around with the python socket module and I have come across an issue.
Here is my python server side script (im using python3.8.2)
import socket
#defin socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 0))
s.listen(5)
while True:
clientsocket, address = s.accept()
print(f"connection from client has been established")
clientsocket.send(bytes("welcome to the server!", "utf-8"))
My server side script runs fine, however when i run the client script
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(127.0.0.1), 0))
msg = s.recv(1024)
print(msg.decode("utf-8"))
i get the following:
File "client.py", line 3
s.connect((socket.gethostname(127.0.0.1), 0))
^
SyntaxError: invalid syntax
I've tried changing the IP to my computer host name and gives the following:
raceback (most recent call last):
File "client.py", line 3, in <module>
s.connect(socket.gethostname((LAPTOP-XXXXXXX), 0))
NameError: name 'LAPTOP' is not defined
There are multiple issues:
when specifying IP addresses and hostnames, they must be formatted as strings (e.g. "127.0.0.1" and "LAPTOP-XXXXXXX"). Specifying them without quotes causes Python to attempt to interpret them as other tokens, such as variable names, reserved keyword, numbers, etc., which fails causing erros such as SyntaxError and NameError.
socket.gethostname() does not take an argument
specifying port 0 in the socket.bind() call results in a random high numbered port being assigned, so you either need to hardcode the port you use or dynamically specify the correct port in your client (e.g. by specifying it as an argument when executing the program)
in the server code, socket.gethostname() may not end up using the loopback address. One option here is using an empty string, which results in accepting connections on any IPv4 address.
Here's a working implementation:
server.py
import socket
HOST = ''
PORT = 45555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
host_addr = s.getsockname()
print("listening on {}:{}".format(host_addr[0], host_addr[1]))
s.listen(5)
while True:
client_socket, client_addr = s.accept()
print("connection from {}:{} established".format(client_addr[0], client_addr[1]))
client_socket.send(bytes("welcome to the server!", "utf-8"))
client.py
import socket
HOST = '127.0.0.1'
PORT = 45555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
msg = s.recv(1024)
print(msg.decode("utf-8"))
Output from the server:
$ python3 server.py
listening on 0.0.0.0:45555
connection from 127.0.0.1:51188 established
connection from 127.0.0.1:51244 established
Output from client:
$ python3 client.py
welcome to the server!
$ python3 client.py
welcome to the server!
Put the 127.0.0.1 as string in gethostname
In the /etc/hosts file content, You will have an IP address mapping with '127.0.1.1' to your hostname. This will cause the name resolution to get 127.0.1.1. Just comment this line. So Every one in your LAN can receive the data when they connect with your ip (192.168.1.*). Used threading to manage multiple Clients.
Here's the Server and Client Code:
Server Code:
import socket
import os
from threading import Thread
import threading
import time
import datetime
def listener(client, address):
print ("Accepted connection from: ", address)
with clients_lock:
clients.add(client)
try:
while True:
client.send(a)
time.sleep(2)
finally:
with clients_lock:
clients.remove(client)
client.close()
clients = set()
clients_lock = threading.Lock()
host = socket.getfqdn() # it gets ip of lan
port = 10016
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(3)
th = []
print ("Server is listening for connections...")
while True:
client, address = s.accept()
timestamp = datetime.datetime.now().strftime("%b %d %Y,%a, %I:%M:%S %p")
a = ("Hi Steven!!!" + timestamp).encode()
th.append(Thread(target=listener, args = (client,address)).start())
s.close()
Client Code:
import socket
import os
import time
s = socket.socket()
host = '192.168.1.43' #my server ip
port = 10016
print(host)
print(port)
s.connect((host, port))
while True:
print((s.recv(1024)).decode())
s.close()
Output:
(base) paulsteven#smackcoders:~$ python server.py
Server is listening for connections...
Accepted connection from: ('192.168.1.43', 38716)
(base) paulsteven#smackcoders:~$ python client.py
192.168.1.43
10016
Hi Steven!!!Feb 19 2020,Wed, 11:13:17 AM
Hi Steven!!!Feb 19 2020,Wed, 11:13:17 AM
Hi Steven!!!Feb 19 2020,Wed, 11:13:17 AM

Python - show path, simple socket problem

I recently ventured into python in 3.7
I want to make a server / client whose client will show the path I put in input (macOS):
Server
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 1337 # Arbitrary non-privileged port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
info = conn.recv(1024)
print(info)
raw_input("Push to exit")
s.close()
Client :
import socket
import os
HOST = '' # The remote host
PORT = 1337 # The same port as used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
print('Connected')
info = os.listdir("/Users/jhon")
s.send(str(info))
s.close()
Server start and it's listening...
python client.py Connected Traceback (most recent call last): File
"client.py", line 10, in
s.send(str(info)) TypeError: a bytes-like object is required, not 'str' (not understand this), and after client start, in server show:
Connected by ('127.0.0.1', 52155) b'' Traceback (most recent call
last): File "server.py", line 13, in
raw_input("press for exit") NameError: name 'raw_input' is not defined (venv) MBP-di-Jhon:untitled1 jhon$
You may want to change the client code to:
HOST = '' # The remote host
PORT = 1337 # The same port as used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
print('Connected')
info = "\n".join(os.listdir("/Users/jhon"))
s.send(info.encode())
s.send(info)
s.close()
os.listdir("/Users/jhon") returns a list, we use join and encode to make it byte object, which is needed for s.send()
You ventured into 3.7 from some 2.x version without modifying the 2.x code. Read something about the differences before continuing. To help you get started:
Replace raw_input with input. (One could replace 2.x input() with eval(input()), but one should nearly always use a more specific evaluator, such as int(input()).)
In 3.x, strings are unicode, whereas sockets still require bytes. Change send and recv to
s.send(str(info).encode())
info = conn.recv(1024).decode()

Python socket.send not working

Simple client - server app.
#Server use decode
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host,port))
s.listen(5)
while True:
c,addr = s.accept()
print("Got connection from " + str(addr))
ret_val = s.send("Thank you".encode('utf-8'))
print ("ret_val={}".format(ret_val))
c.close()
Client:
#client use decode
from socket import gethostname, socket
serSocket = socket()
server = gethostname()
port = 12345
serSocket.connect((server, port))
data = serSocket.recv(1024)
msg = data.decode('utf-8')
print("Returned Msg from server: <{}>".format(msg))
serSocket.close()
when the server tries to send the following exception occurred
Traceback (most recent call last):
Got connection from ('192.168.177.1', 49755)
File "C:/Users/Oren/PycharmProjects/CientServer/ServerSide/Server2.py", line 16, in <module>
ret_val = s.send("Thank you".encode('utf-8'))
OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
Process finished with exit code 1
As can be seen the client connects the server successfully.
But send fails.
What is the problem?
The problem is that you are sending on the listening socket, not on the connected socket. connect returns a new socket which is the one you must use for data transfer. The listening socket can never be used for sending or receiving data.
Change the send to this and your program will work fine:
ret_val = c.send("Thank you".encode('utf-8'))
(Note c.send, not s.send)

how to execute one script from another

I am new in working with python and working on API of XenServer
I am trying to start a script which uses the XenServer API to start a virtual machine upon receiving the data from the client. The code is below
import socket
import json
import startvm
ip = socket.gethostbyname(socket.gethostname())
print("ip of server machiene = " + ip )
# create a socket object
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
host = "127.0.0.1"
port = 9999
# bind to the port
serversocket.bind((host, port))
print ("server is waiting for data")
# queue up to 5 requests
serversocket.listen(5)
running = True
while True:
# establish a connection
clientsocket, addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
while running:
receivedData = clientsocket.recv(1024)
#json = receivedData
if receivedData:
print (receivedData)
execfile(startvm.py)
else:
print (" -- data end --" )
running = False
serversocket.close()
I am using execute(script name). and it gives me the following error
on the server side script
ip of server machine = 192.168.0.11
server is waiting for data
Traceback (most recent call last):
Got a connection from ('127.0.0.1', 50128)
File "/Users/jasmeet/IdeaProjects/vKey-cloud/server.py", line 45, in
<module>
0
execfile(startvm.py)
AttributeError: 'module' object has no attribute 'py'
and this on client script
connecting to server at 127.0.0.1 on port 9999
Traceback (most recent call last):
File "/Users/jasmeet/IdeaProjects/vKey-cloud/client.py", line 27, in
<module>
clientSocket.send(str(x))
socket.error: [Errno 32] Broken pipe
can anybody explain me how to do it exactly thank you in advance
you could import the file at the beginning like:
from startvm.py import A_FUNCTION_FROM_THAT_FILE
so that it's optimized
and replace
execfile(startvm.py)
with
A_FUNCTION_FROM_THAT_FILE(*args)
ex:
# script A.py
from B.py import customfunc
customfunc(2, 4)
# script B.py
def customfunc(x, y):
return x*y
writing the following code for server.py solved my problem
# server.py
import socket
import json
import startvm
ip = socket.gethostbyname(socket.gethostname())
print("ip of server machiene = " + ip )
# create a socket object
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
#host = socket.gethostname()
#port = 9999 # port 80
host = "127.0.0.1"
port = 9999
# bind to the port
serversocket.bind((host, port))
print ("server is waiting for data")
# queue up to 5 requests
serversocket.listen(5)
while True:
running = True
# establish a connection
clientsocket, addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
while running:
receivedData = clientsocket.recv(1024)
#json = receivedData
if receivedData:
print (receivedData)
#execfile('startvm.py')
else:
print (" -- data end --" )
running = False

Categories

Resources