Need help in Python3 - sockets

I have the below code that i am trying the run using python3.2 interpreter.
import socket #for sockets
import sys #for exit
#from UserString import MutableString
#create an INET, STREAMing socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print ('Failed to create socket')
sys.exit()
print ('Socket Created')
host = 'www.google.com';
port = 80;
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
#could not resolve
print ('Hostname could not be resolved. Exiting')
sys.exit()
#Connect to remote server
s.connect((remote_ip , port))
print ('Socket Connected to ' + host + ' on ip ' + remote_ip)
#Send some data to remote server
message = "GET / HTTP/1.0\r\n\r\n"
try :
#Set the whole string
s.sendall(message.encode())
except socket.error:
#Send failed
print ('Send failed')
sys.exit()
print ('Message send successfully')
#Now receive data
messageParts = []
remaining = 4096
chunk = s.recv(remaining)
messageParts.append(chunk)
while (len(chunk) > 0):
chunk = s.recv(remaining)
messageParts.append(chunk.decode())
finalMessage = b"".join(messageParts)
print('Printing the html contents ...')
print(finalMessage)
Upon running the above code, with python version 3.2, i get the below error:
Socket Created
Socket Connected to www.google.com on ip 74.125.201.147
Message send successfully
Traceback (most recent call last):
File "TestMainServerV2.py", line 73, in <module>
finalMessage = b"".join(messageParts)
TypeError: sequence item 1: expected bytes, str found
Could anybody let me know what is the issue?
Thanks!

messageParts.append(chunk.decode())
is appending strs to messageParts.
chunk = s.recv(remaining)
messageParts.append(chunk)
is appending bytes to messageParts. (Everything that comes through a socket is bytes so chunk is a bytes object.)
Especially in Python3, one should never mix strs and bytes.
b"".join(messageParts)
raises a TypeError since b"".join expects only bytes.
You can avoid the problem by not decoding chunk. Use
messageParts.append(chunk)
instead of
messageParts.append(chunk.decode())

Related

TypeError: must be str, not bytes , Python 3, Raspberry pi

I am trying to send video from raspberry pi to my laptop via laptop
and save them as pictures so i found the below code online
but I get the following errors when I run them
so i run this client code on the pi using Thonny ide that comes preloaded
, I apologize for the way code is formatted below and would be very grateful if anybody can help me sort this out
Server on the laptop is run using python 3.6 idle
import sys
import numpy as np
import cv2
import socket
class VideoStreamingTest(object):
def __init__(self):
self.server_socket = socket.socket()
self.server_socket.bind(('0.0.0.0', 9006))
self.server_socket.listen(0)
self.connection, self.client_address = self.server_socket.accept()
self.connection = self.connection.makefile('rb')
self.streaming()
def streaming(self):
try:
print("Connection from: ", self.client_address)
print("Streaming...")
print("Press 'q' to exit")
stream_bytes = ' '
while True:
stream_bytes += self.connection.read(1024)
first = stream_bytes.find('\xff\xd8')
last = stream_bytes.find('\xff\xd9')
if first != -1 and last != -1:
jpg = stream_bytes[first:last + 2]
stream_bytes = stream_bytes[last + 2:]
#image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.CV_LOAD_IMAGE_GRAYSCALE)
image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.CV_LOAD_IMAGE_UNCHANGED)
cv2.imshow('image', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
self.connection.close()
self.server_socket.close()
if __name__ == '__main__':
VideoStreamingTest()
I get the following error
Connection from: ('192.168.43.3', 47518)
Streaming...
Press 'q' to exit
Traceback (most recent call last):
File "C:\Users\John Doe\d-ff\Desktop\AutoRCCar-master
3\test\stream_server_test.py", line 46, in <module>
VideoStreamingTest()
File "C:\Users\John Doe\d-ff\Desktop\AutoRCCar-master
3\test\stream_server_test.py", line 16, in __init__
self.streaming()
File "C:\Users\John Doe\d-ff\Desktop\AutoRCCar-master
3\test\stream_server_test.py", line 28, in streaming
stream_bytes += self.connection.read(1024)
TypeError: must be str, not bytes
Client side on the pi
import io
import socket
import struct
import time
import picamera
# create socket and bind host
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('ToM', 9006))
connection = client_socket.makefile('wb')
try:
with picamera.PiCamera() as camera:
camera.resolution = (320, 240) # pi camera resolution
camera.framerate = 5 # 10 frames/sec
time.sleep(2) # give 2 secs for camera to initilize
start = time.time()
stream = io.BytesIO()
# send jpeg format video stream
for foo in camera.capture_continuous(stream, 'jpeg', use_video_port = True):
connection.write(struct.pack('<L', stream.tell()))
connection.flush()
stream.seek(0)
connection.write(stream.read())
if time.time() - start > 600:
break
stream.seek(0)
stream.truncate()
connection.write(struct.pack('<L', 0))
finally:
connection.close()
client_socket.close()
I get the following error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/pi/Desktop/stream_client.py", line 40, in <module>
connection.close()
File "/usr/lib/python3.5/socket.py", line 594, in write
return self._sock.send(b)
BrokenPipeError: [Errno 32] Broken pipe
I first thought it might be because of the limited bandwidth since i was running vnc viewer (remote desktop) via wifi on the pi but I don't think it is
I also had same problem. After some searching I found solution.
In python 3 we have to specify whether string is regular string or binary.Thats why we use b'string' instead of just 'string'
Change
stream_bytes = ' '
to
stream_bytes = b' '
Also change
first = stream_bytes.find('\xff\xd8')
last = stream_bytes.find('\xff\xd9')
to
first = stream_bytes.find(b'\xff\xd8')
last = stream_bytes.find(b'\xff\xd9')
Note that you are using cv2.CV_LOAD_IMAGE_UNCHANGED which is not available in opencv3.0
Use cv2.IMREAD_COLOR to show image in color.
Edit these changes and your stream should run smoothly.
connection.write(struct.pack('<L', 0))
Check out by inserting the above within try

How can I take my captured information from a network/port scan and write that to a file?

I wrote an IP and port scanning program and I want to take the captured data and output it to a text file. I've been trying to figure it out for a while and haven't had any luck applying what I can find in searches. At the end, I commented out how I thought it should work to write the information to a file.
Any help or suggestions would be greatly appreciated, I'm still somewhat new to Python and trying to learn.
#!/usr/bin/env python
import ipaddress
import sys, time
import os
import subprocess
import socket
from datetime import datetime
FNULL = open(os.devnull, 'w')
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print ('Welcome to the IP/Port Scanner and Logger')
address = input('Enter starting IP address: ')
split1 = first,second,third,fourth = str(address).split('.')
start = int(fourth)
host = first+'.'+second+'.'+third+'.'+str(start)
end_address = input('Enter the ending IP address: ')
split2 = first,second,third,fourth = str(end_address).split('.')
end = int(fourth)
network = first+'.'+second+'.'+third+'.'
min_port = input("Enter starting port range: ")
max_port = input("Enter ending port range: ")
remoteserver = host
remoteserverIP = socket.gethostbyname(remoteserver)
def port_scan():
print ('Port scanning function initialized:')
try:
for port in range(int(min_port),int(max_port)):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((remoteserverIP, port))
if result == 0:
print ('Port ' + str(port) + ': Open')
sock.close()
except KeyboardInterrupt:
print ("You halted the process")
sys.exit()
except socket.gaierror:
print ('Hostname could not be resolved. Exiting')
sys.exit()
except socket.error:
print ("Couldn't connect to server")
sys.exit()
return port
def check_up():
for ip_address in range(int(start), int(end)):
try:
subprocess.check_call(['ping', '-c', '2',
network + str(ip_address)],
stdout=FNULL,stderr=FNULL)
except (OSError, subprocess.CalledProcessError):
print ("{}{}".format(network,ip_address), "is down")
except KeyboardInterrupt:
print ("You halted the process")
sys.exit()
else:
print ("{}{}".format(network,ip_address), "is up")
return ip_address
check_up()
time1 = datetime.now()
time2 = datetime.now()
scantime = time2-time1
print ('Scan completed in: ', scantime)
while True:
print ('Would you like to write information to file?')
answer = input()
if answer in ['yes', 'y', 'yeah']:
print ('Alright, writing to file')
print ('Program will exit upon scan completion.')
break
elif answer in ['no', 'n']:
print ('Okay, exiting now..')
sys.exit()
break
else:
print ('Please enter a yes or no value')
###Output File
##with open('ipscan.txt', 'w+') as ip:
## print (ip_address, port)
##
##sys.exit()

Incorrect throughput value in python

I am writing a python code to find throughput between server and client. It is based on speedtest.net functionality where I am sending a dummy file to calculate the speed. The problem I am facing is unreliable throughput output. I will appreciate your suggestions on the same. Here is the code.
server.py
import socket
import os
port = 60000
s = socket.socket()
host = socket.gethostname()
s.bind((host, port))
s.listen(5)
print 'Server listening....'
while True:
conn, addr = s.accept()
print 'Got connection from', addr
data = conn.recv(1024)
print('Server received', repr(data))
filename='akki.txt'
b = os.path.getsize(filename)
f = open(filename,'rb')
l = f.read(b)
while (l):
conn.send(l)
l = f.read(b)
f.close()
print('Done sending')
conn.send('Thank you for connecting')
conn.close()
Client.py
import socket
import time
import os
s = socket.socket()
host = socket.gethostname()
port = 60000
t1 = time.time()
s.connect((host, port))
s.send("Hello server!")
with open('received_file', 'wb') as f:
print 'file opened'
t2 = time.time()
while True:
data = s.recv(1024)
if not data:
break
f.write(data)
t3 = time.time()
print data
print 'Total:', t3 - t1
print 'Throughput:', round((1024.0 * 0.001) / (t3 - t1), 3),
print 'K/sec.'
f.close()
print('Successfully received the file')
s.close()
print('connection closed')
Output when sending akki.txt
Server Output
Server listening....
Got connection from ('10.143.47.165', 60902)
('Server received', "'Hello server!'")
Done sending
Client output
file opened
Raw timers: 1503350568.11 1503350568.11 1503350568.11
Total: 0.00499987602234
**Throughput: 204.805 K/sec.**
Successfully received the file
connection closed
Output for ak.zip ( which is bigger file)
Client output
file opened
Total: 0.0499999523163
**Throughput: 20.48 K/sec.**
Successfully received the file
connection closed
Short Answer: you need to take the file size into consideration.
More Details:
Throughput is data/time. Your calculation:
round((1024.0 * 0.001) / (t3 - t1), 3)
Doesn't take the file size into account. Since sending a large file takes more time, 't3-t1' is bigger so your throughput is smaller (same numerator with larger denominator). Try adding the file size to the formula and you should get much more constant results.
Hope this helps.

'str' does not support the buffer interface - Python 3 [duplicate]

This question already has an answer here:
TypeError: str does not support buffer interface [duplicate]
(1 answer)
Closed 6 years ago.
import socket
serverName = "hostname"
serverPort = 12000
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
message = input('input lowercase sentence:')
clientSocket.sendto(message, (serverName, serverPort))
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
print (modifiedMessage)
clientSocket.close()
gives this error
Traceback (most recent call last):
File "C:/Python34/server1.py", line 11, in <module>
clientSocket.sendto(message, (serverName, serverPort))
TypeError: 'str' does not support the buffer interface
What do I do?
I've encode this code
import socket
serverName = "hostname"
serverPort = 12000
clientSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
message = input('input lowercase sentence:').encode('ascii')
clientSocket.sendto(message,(serverName, serverPort))
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
print (modifiedMessage.decode('ascii'))
clientSocket.close()
But it still error
Traceback (most recent call last):
File "J:\Sistem Jaringan\Task I\client.py", line 11, in <module>
clientSocket.sendto(message,(serverName, serverPort))
socket.gaierror: [Errno 11004] getaddrinfo failed
How can i fix it?
Sockets sent bytes to the other end of the connection. Encode strings to bytes before trying to send. In the sendto method, change message to message.encode(). Add argument encoding='xyz' if you do not want the default utf-8 encoding. The modifiedMessage you receive will also be bytes, and you may want to decode it to a string.

Python 3: Server socket not closing properly, infinite loop of blank messages received

EDIT: I solved this question myself, look at the first answer if you have a similar issue
I am new to sockets and made a client-server test modifying one example, it sends and receives data ok but when closing the server get caught in a loop receiving blank messages and I can't find out why even though I use shutdown(socket.SHUT_RDWR) to close the connection immediately according to the documentation.
I had to use two cmd of windows for each one (server and client) because when running first the server in idle and then the client I got in client_example ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it here is the code. Anyways, here it is the sequence I tried:
(in the client console):
c:\python33\python client_example.py
SEND( TYPE q or Q to Quit):Hi
SEND( TYPE q or Q to Quit):q
(in the server console):
c:\python33\python server_example3.py
TCPServer Waiting for client on port 7000
I got a connection from ('127.0.0.1', 49263)
RECEIVED: b'Hi'
RECEIVED: b''
RECEIVED: b''
RECEIVED: b''
RECEIVED: b''
RECEIVED: b''
.... <---After I did CTRL+C
Traceback (most recent call last):
File "server_example.py", line 19, in <module>
print("RECEIVED:",data)
File "c:\python33\lib\encodings\cp850.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_map)[0]
KeyboardInterrupt
Here is the code of the server and client:
server_example.py:
#TCP server example
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 7000))
server_socket.listen(5)
print("TCPServer Waiting for client on port 7000")
while 1:
client_socket, address = server_socket.accept()
print("I got a connection from ", address)
while 1:
data = client_socket.recv(32)
if (data == 'q' or data == 'Q'):
client_socket.shutdown(socket.SHUT_RDWR)
client_socket.close()
break;
else:
print("RECEIVED:",data)
client_example.py:
# TCP client example
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("localhost", 7000))
while 1:
data = input( "SEND( TYPE q or Q to Quit):" )
if (data != 'Q' and data != 'q'):
my_bytes = bytearray()
for c in data:
my_bytes.append(ord(c))
client_socket.send(my_bytes)
else:
client_socket.shutdown(socket.SHUT_RDWR)
client_socket.close()
break;
Well, I feel dumb that I solved this thing after 11 minutes of posting the question when I was unable to solve it for 2 hours...
The problem was that I was comparing data with the string 'q' which was correct in python 2 but in python 3 what is being sent are bytes, b'q' <> 'q' ...
Here is the corrected code:
server_example.py
#TCP server example
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 7000))
server_socket.listen(5)
print("TCPServer Waiting for client on port 7000")
while 1:
client_socket, address = server_socket.accept()
print("I got a connection from ", address)
while 1:
data = client_socket.recv(32)
print("RECEIVED:",data)
if (data == b'q' or data == b'Q'):
## client_socket.shutdown(socket.SHUT_RDWR)
client_socket.close()
break;
break;
client_example.py
# TCP client example
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("localhost", 7000))
while 1:
data = input( "SEND( TYPE q or Q to Quit):" )
if (data != 'Q' and data != 'q'):
my_bytes = bytearray()
for c in data:
my_bytes.append(ord(c))
client_socket.send(my_bytes)
else:
my_bytes = bytearray()
my_bytes.append(ord(data))
client_socket.send(my_bytes)
## client_socket.shutdown(socket.SHUT_RDWR)
client_socket.close()
break;
You're assuming you're going to get the Q. You should also engage in the same processing when you get EOS from read, whatever form that takes in Python.
#EJP : By EOS you mean end of stream? If so you are right, this example was a very simple one to get started in which I overlooked details like these.
Anyway I found that using this check in the server it is solved:
data = input( "SEND( TYPE q or Q to Quit):" )
if (data == b''):
break;