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)
Related
im trying to send an http request to google, but all I receive is empty (b""). Here is my 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))
print("Connected...")
request = "GET / HTTP/1.1\r\nHost:%s\r\n\r\n" % target_host
response = client.recv(4096)
http_response = repr(response)
http_response_len = len(http_response)
print("[+RECV+] - length %d" % http_response_len)
print(http_response)
Here is my response:
[+RECV+] - length 3
b''
(also it took like 240 seconds to complete the request, is that normal?)
Thanks!
My bad, I forgot to send the data with
client.send(request.encode())
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'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.
I have to create a web server in Python. Below is the code I am working on. When i execute it, I initially get no error and it prints "Ready to serve.." , but after opening a browser and running http://10.1.10.187:50997/HelloWorld.html (HelloWorld is an html file in the same folder as my python code, while 10.1.10.187 is my IP address and 50997) is the server port), I get a TypeError saying 'a bytes like object is required and not str". please help me in resolving this and kindly let me know if any other modifications are required.
#Import socket module
from socket import *
#Create a TCP server socket
#(AF_INET is used for IPv4 protocols)
#(SOCK_STREAM is used for TCP)
# Assign a port number
serverPort = 50997
serverSocket = socket(AF_INET, SOCK_STREAM)
#serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#print ("hostname is: "), gethostname()
#print ("hostname is: "), socket.gethostname()
# Bind the socket to server address and server port
serverSocket.bind(("", serverPort))
# Listen to at most 1 connection at a time
serverSocket.listen(1)
# Server should be up and running and listening to the incoming connections
while True:
print ("Ready to serve...")
# Set up a new connection from the client
connectionSocket, addr = serverSocket.accept()
try:
# Receives the request message from the client
message = connectionSocket.recv(1024)
print ("Message is: "), message
filename = message.split()[1]
print ("File name is: "), filename
f = open(filename[1:])
outputdata = f.read()
connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n")
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.send("\r\n")
# Close the client connection socket
connectionSocket.close()
except IOError:
# Send HTTP response message for file not found
connectionSocket.send("HTTP/1.1 404 Not Found\r\n\r\n")
connectionSocket.send("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n")
# Close the client connection socket
connectionSocket.close()
serverSocket.close()
The error I am exacly getting-
Ready to serve...
Message is:
File name is:
Traceback (most recent call last):
File "intro.py", line 56, in <module>
connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n")
TypeError: a bytes-like object is required, not 'str'
You need to convert the string you are sending into bytes, using a text format. A good text format to use is UTF-8. You can implement this conversion like so:
bytes(string_to_convert, 'UTF-8')
or, in the context of your code:
connectionSocket.send(bytes("HTTP/1.1 404 Not Found\r\n\r\n","UTF-8"))
connectionSocket.send(bytes("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n","UTF-8"))`
import socket
# Set up a TCP/IP socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# Connect as client to a selected server
# on a specified port
s.connect(("www.wellho.net",80))
# Protocol exchange - sends and receives
s.send("GET /robots.txt HTTP/1.0\n\n")
while True:
resp = s.recv(1024)
if resp == "": break
print(resp,)
# Close the connection when completed
s.close()
print("\ndone")
Error:
cg0546wq#smaug:~/Desktop/440$ python3 HTTPclient.py
Traceback (most recent call last):
File "HTTPclient.py", line 11, in <module>
s.send("GET /robots.txt HTTP/1.0\n\n")
TypeError: 'str' does not support the buffer interface
Can NOT use
urllib.request.urlopen
urllib2.urlopen
http
http.client
httplib
Sockets can only accept bytes, while you are trying to send it a Unicode string instead.
Encode your strings to bytes:
s.send("GET /robots.txt HTTP/1.0\n\n".encode('ascii'))
or give it a bytes literal (a string literal starting with a b prefix):
s.send(b"GET /robots.txt HTTP/1.0\n\n")
Take into account that data you receive will also be bytes values; you cannot just compare those to ''. Just test for an empty response, and you probably want to decode the response to str when printing:
while True:
resp = s.recv(1024)
if not resp: break
print(resp.decode('ascii'))
import socket
# Set up a TCP/IP socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# Connect as client to a selected server
# on a specified port
s.connect(("www.google.com",80))
# Protocol exchange - sends and receives
s.send(b"GET /index.html HTTP/1.0\n\n")
while True:
resp = s.recv(1024)
if resp == b'': break
print(resp,)
# Close the connection when completed
s.close()
print("\ndone")