I started reading the book "Black hat python" and upon writing the very 1st TCP client example I get the error
AttributeError: 'socket' object attribute 'send' is read-only
The code is as follows:
import socket
target_host = "google.com"
target_port = 80
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((target_host,target_port))
client.send = ("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")
response = client.recv(4096)
print response
Where could the mistake be?
Related
I have an error when I create a simple TCP client:
Exception has occurred: TypeError a bytes-like object is required, not 'str' in line client.send("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")
My Python version is 3.8.
import socket
target_host = "www.google.com"
target_port = 80
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))
client.send("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")
response = client.recv(4096)
print(response)
I am trying to execute subprocess on my other pc with sockets.
import socket
import subprocess
def command_execution(command_exec):
return subprocess.check_output(command_exec, shell=True)
ip, port = "192.168.1.46", 8080
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.connect((ip, port))
connection.send(b"Conncetion OK !\n")
command = connection.recv(1024)
copt = command_execution(command)
connection.send(copt)
connection.close()
Getting this error -->
nextchar = self.instream.read(1)
AttributeError: 'bytes' object has no attribute 'read'
I am troubling with that Attribute Error. How can i fix this ?
It works without subprocess
Solved.
import socket
import subprocess
def command_execution(command):
return subprocess.check_output(command, shell=True)
ip, port = "192.168.1.46", 8080
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.connect((ip, port))
connection.send(b"Conncetion OK !\n")
command = connection.recv(1024)
command_output = command_execution(command.decode("ascii"))
connection.send(command_output.encode('ascii'))
connection.close()
The problem was, connection.recv() takes data in binary, but subprocess needs string data. So first decode connection.rev() to string, pass it to subprocess_checkoutput function, than take output to convert it back to binary, so connection.send() can work.
I've trying to follow this book's code, but is written in python 2. At first, I tried to run the book's code:
import socket
target_host = "www.google.com"
target_port = 80
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host,target_port))
msg = "Hi!"
"""MSG = msg.encode()"""
client.send(msg)
response = client.recv(4096)
print(response)
Then it run into this error: TypeError: a bytes-like object is required, not 'str'. Which I corrected with some encoding like this:
import socket
target_host = "www.google.com"
target_port = 80
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host,target_port))
msg = "Hi!"
MSG = msg.encode()
client.send(MSG)
response = client.recv(4096)
print(response)
But now, the code doesn't print anything. What can be wrong?
The book's code is send "GET / HTTP/1.1\Host: google.com\r\n\r\n".
This code means send a get request to google, so it can get response for request you sent .
Your msg is not a HTTP's request, so google will not send response for you msg.
Basically I'm just starting out with python networking and python in general and I can't get my TCP client to send data. It says:
Traceback (most recent call last):
File "script.py", line 14, in <module>
client.send(data) #this is where I get the error
TypeError: a bytes-like object is required, not 'str'
The code is as follows:
import socket
target_host = "www.google.com"
target_port = 80
#create socket object
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#connect the client
client.connect((target_host,target_port))
#send some data
data = "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"
client.send(data) #this is where I get the error
#receive some data
response = client.recv(4096)
print(response)
Thanks for your help in advance!
You are probably using Python 3.X. socket.send() expected a bytes type argument but data is an unicode string. You must encode the string using str.encode() method. Similarly you would use bytes.decode() to receive the data:
import socket
target_host = "www.google.com"
target_port = 80
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host,target_port))
data = "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"
client.send(data.encode('utf-8'))
response = client.recv(4096).decode('utf-8')
print(response)
If you are using python2.x your code is correct. As in the documentation for python2 socket.send() takes a string parameter. But if you are using python3.x you can see that socket.send() takes a bytes parameter. Thus you have to convert your string data into bytes using str.encode(). So your code might look like this instead.
import socket
target_host = "www.google.com"
target_port = 80
#create socket object
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#connect the client
client.connect((target_host,target_port))
#send some data
data = "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"
client.send(data.encode('utf-8'))
#receive some data
response = client.recv(4096)
print(response)
So I encoded the data with utf-8 as was suggested by a few people and rewrote my code which fixed the odd syntax error. Now my code works perfectly. Thank you to everyone who posted but especially to #FJSevilla. The working code is as follows:
import socket
target_host = "www.google.com"
target_port = 80
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host,target_port))
data = "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"
client.send(data.encode('utf-8'))
response = client.recv(4096).decode('utf-8')
print(response)
Another suggestion using Python 3.7 is to add the letter "b" in the message. For example:
s.send(b"GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")
import socket
t_host = "www.google.com"
t_port = 80
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((t_host, t_port))
s.send(b"GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")
response = s.recv(4096)
print(response)
I saw a similar question been asked a year ago but no solution was found for the problem. Hope to find it now.
I'm trying to figure out how does network programming work and found this code example of a basic server:
import socket
import time
# create a socket object
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 9999
# bind to the port
serversocket.bind((host, port))
# queue up to 5 requests
serversocket.listen(5)
while True:
# establish a connection
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
currentTime = time.ctime(time.time()) + "\r\n"
clientsocket.send(currentTime.encode('ascii'))
clientsocket.close()
But as I run the code it says that 'socket' object attribute 'bind' is read-only. I tried to replace both ip to '0.0.0.0' and port number to 8080 or just ' ' but nothing worked.