Cyclic Redundancy Check comparison has different values - python

There are 3 codes that need to do the following actions:
A sends a message to B along with the CRC32 code.
B receives this message and CRC32 code.
B follows a 40% probability to change the message.
B sends the message along with the original CRC32 code to C.
C receives the message and CRC32 code and check whether it is correct or not.
For some reason, in part C when I compare the CRC's they are never equal, what am I missing?
Part A:
import socket
import struct
import sys
import binascii
def crc32(v):
r = binascii.crc32(v.encode())
return r
if len(sys.argv) != 3:
print("Useage: python " + sys.argv[0] + " <ip> <liseten port>")
sys.exit(-1)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
print("Input text:")
text = sys.stdin.readline().strip()
ss = struct.pack("!50sL",text.encode(),crc32(text))
s.sendto(ss,(sys.argv[1],int(sys.argv[2])))
if text == "bye":
break
Part B:
import socket
import operator
import sys
import binascii
import struct
import random
def crc32(v):
return binascii.crc32(v.encode())
if len(sys.argv) != 3:
print("Useage: python " + sys.argv[0] + " <liseten port>")
sys.exit(-1)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("0.0.0.0", int(sys.argv[1])))
print("Waiting...")
while True:
data, addr = s.recvfrom(1024)
str,crc = struct.unpack("!50sL",data)
str = str.decode("utf-8").replace("\0","")
if random.randint(0,100) < 40:
str = str + "x"
print("str:%s\ncrc:%X" % (str,crc & 0xffffffff))
str2 = str.encode("utf-8")
tpack = struct.pack("!50sL", str2, crc)
s.sendto(tpack,("127.0.0.1",int(sys.argv[2])))
if str == "bye":
break
Part C:
import socket
import operator
import sys
import binascii
import struct
def crc32(v):
return binascii.crc32(v.encode())
if len(sys.argv) != 2:
print("Useage: python " + sys.argv[0] + " <liseten port>")
sys.exit(-1)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("0.0.0.0", int(sys.argv[1])))
print("Waiting...")
while True:
data, addr = s.recvfrom(1024)
str,crc = struct.unpack("!50sL",data)
str = str.decode("utf-8")
print("str:%s\ncrc:%X" % (str,crc & 0xffffffff))
ncrc = crc32(str)
if ncrc == crc:
print("both messages are the same")
if str == "bye":
break

You forgot to replace the null bytes in Part C. You calculated the CRC in Part A before packing to 50 bytes, and removed them in Part B when displaying the received value.
str = str.decode("utf-8")
should b:
str = str.decode("utf-8").replace('\0','')
Note: str is a builtin function that you lose access to by using it as a variable name.

Related

UDP client-server. Client not sending string to the server

I'm trying to split string if even or odd for example:
"Tea" will return two strings string1 = "Te" and string2 = "a" - odd
"Coffee" will return two strings string1 = "Cof" and string2 = "fee"
I've got a working algorithm that does that.
Then client needs to send this to the server. My question how to send this to the server. How server accepts these two strings?
I'm newbie to python. Please help.
Server side:
import socket
def Main():
host = '127.0.0.1'
port = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
print("Server Started")
while True:
data, addr = s.recvfrom(1024)
data = data.decode('utf-8')
print("Message From: " +str(addr))
print("From connected user: " + data)
data = data.upper()
print("Sending: " + data)
s.sendto(data.encode('utf-8'), addr)
s.close()
if __name__ == '__main__':
Main()
Client side:
import socket
def Main():
host = '127.0.0.1'
port = 5001
server = ('127.0.0.1', 5000)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
message = input('Please type a word ')
while message != '':
def splitWord(w):
split = -((-len(w))//2)
s1 = (w[:split])
s2 = (w[split:])
print(s1)
print(s2)
return
a = splitWord(message)
s.sendto(a.encode('utf-8'), server)
data, addr = s.recvfrom(1024)
data = data.decode('utf-8')
print("Received from server: " + data)
message = input('-> ')
s.close()
if __name__ == '__main__':
Main()
You might want to revisit your splitWord() function.
Inside splitWord() you create two substrings: s1 and s2, but don't do anything with them (other than printing). Your return is empty, and you don't modify the argument either.
A better way of to define this function is:
def splitWord(w):
return w[:len(w)/2], w[len(w)/2:]
Example:
a = "Coffee"
f,s = splitWord(a)
print f, s
-> Cof fee
Also there is no reason to define splitWord() inside the while loop.

is the logic behind my trivial tftp client flawed?

I'm still a student so I might have missed something really obvious.
So I am stressing out about this so much.
But anyway here's my TFTP python code, all it does is downloading a text-file from our lecturer's server.
The file generated by it looks like this:
http://pastebin.com/TP8hngxM
And the original file like this:
http://pastebin.com/xDMjkABp
And if you run it through a difference checker, the difference is miniscule and in only 1 specific spot and it's really difficult for me to figure out why is this happening.
The downloaded file has a few extra words.
If you have spare 5 minutes, could you please check out my nested while loop (everything else was provided by the lecturer and can't be changed) to see if there's anything wrong with it?
The worst thing is that I've already had it working, but I lost my memory stick and I lost the most up-to-date version of the program that was running 100% fine.
So as I said, it's only about the nested while loop, I' not allowed to change anything above it.
#!/usr/bin/python
import struct
import sys
import os
import select
import glamnetsim
from socket import *
serverHost = 'mcgreg.comp.glam.ac.uk'
serverPort = 69
timeoutSecs = 5
debugging = False
RRQ, WRQ, DATA, ACK, ERROR = range(1, 6)
codeDescriptions = {RRQ:"RRQ", WRQ:"WRQ", DATA:"DATA", ACK:"ACK", ERROR:"ERROR"}
def printf (format, *args):
print str(format) % args,
def finish ():
printf("you should see\n1e951df315d433aa4df2065a1ad31311\n")
os.system("md5sum newfile.txt")
sys.exit(0)
def sendPacket (packet, port):
global sock, debugging
global serverIp
if debugging:
for i in packet:
print ('%02x' % ord(i)),
print ''
sock.sendto(packet, (serverIp, port))
def sendReadRequest (filename, mode):
global serverPort
format = "!H%ds" % (len(filename)+1)
format += "%ds" % (len(mode)+1)
s = struct.pack(format, 1, filename, mode)
sendPacket(s, serverPort)
def sendRealAck(blockno, port):
s = struct.pack("!H", 4)
s += struct.pack("!H", blockno)
sendPacket(s, port)
def sendACK (blockno, port):
print " -> ACK:%d\n" % blockno
if blockno == 0:
sendReadRequest("the_machine_stops.txt", "octet")
else:
sendRealAck(blockno, port)
def stripPacket (s):
if len(s)>3:
code = struct.unpack("!H", s[:2])[0]
blockno = struct.unpack("!H", s[2:4])[0]
data = s[4:]
code, data = glamnetsim.simulatePossibleError (code, data)
return code,blockno,data
else:
debugPrint("corrupt packet")
return -1,-1,""
def debugPrint (s):
global debugging
if debugging:
print s
def getDesc (c):
global codeDescriptions
return codeDescriptions[c]
sock = socket(AF_INET, SOCK_DGRAM)
serverIp = gethostbyname(serverHost)
sock.setblocking(1)
sendReadRequest("the_machine_stops.txt", "netascii")
lastblock = 0
blockno = 0
port = serverPort
f = open("newfile.txt", "w")
while True:
while True:
if blockno == lastblock+1:
break
r, w, x = select.select([sock], [], [], 5.0)
if r == []:
sendACK(lastblock, port)
else:
(packet, (address, port)) = sock.recvfrom(512+4)
code, newblock, text = stripPacket(packet)
print code, blockno
if code is 3:
blockno = newblock
sendACK(blockno, port)
if code is 5:
sendACK(lastblock, port)
print "Bn: " + str(blockno) + " Lb: " + str(lastblock)
lastblock = blockno
f.write(text)
print "OK"
if len(text) < 512:
break
f.close()
finish()
f.write(text)
That line is run with a stale value if blockno == lastblock+1. It probably should be within the inner loop.

Python 3.4.2 - Socket module is not callable

from socket import *
import _thread
from My_TCP_callable import *
IP_list = []
port_list = []
def IP_find(IP_list):
IPtarget = input("Enter host to scan: ")
IP_list = []
print ('Starting scan on host ', IPtarget)
for ip in range(1, 256):
s = socket(AF_INET, SOCK_STREAM)
addr = IPtarget + str(ip)
result = s.connect_ex((addr, 135))
print (ip)
if(result == 0):
print ('IP %d: OPEN' % (addr,))
IP_list.append(str(addr))
s.close()
print("Open ports: %s" % (port_list))
sending_socket(port_list)
return
def port_find(port_list):
if __name__ == '__main__':
target = input('Enter host to scan: ')
possible_list = []
port_list = []
typ = int(input(" 1.Use standard ports \n 2.Set a range of points \n 3+.Set a number of specific points "))
if typ == 1:
possible_list = [20, 1025]
else:
for number in range(typ):
v = int(input("Set a port point: "))
possible_list.append(v)
if typ >= 3:
x = (possible_list)
else:
x = range(min(possible_list), max(possible_list))
targetIP = gethostbyname(target)
print ('Starting scan on host ', targetIP)
#scan reserved ports
for i in x:
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((targetIP, i))
if(result == 0):
print ('Port %d: OPEN' % (i,))
port_list.append(str(i))
s.close()
print("Open ports: %s" % (port_list))
return port_list
def sending_socket(port_list):
send_socket = input("Would you like to send a socket with this? ")
if send_socket == "yes":
port = int(input("Which port would you like to search? "))
message = input("What would you like to send? ")
My_TCP_callable.connect(targetIP, port, message)
elif send_socket == "automate":
message = "Alive"
for ports in port_list:
_thread.start_new_thread(connect ,(targetIP, ports, message))
return
IP_find(IP_list)
Every time I call this code an error comes up:
File "C:\Users\as009542\Desktop\python\Networking\scanner.py", line 81, in
<module>
IP_find(IP_list)
File "C:\Users\as009542\Desktop\python\Networking\scanner.py", line 15, in IP_find
s = socket(AF_INET, SOCK_STREAM)
TypeError: 'module' object is not callable
I've checked around and used this in other programs but I cant figure out why the socket can't create.
This code is not pretty or complete however I can't continue making it until I fix this problem, the last function 'sending_socket' is being called from a different file called 'My_TCP_callable' although this does not affect the problem I am having.
You are probably using import socket in your module My_TCP_callable
Because you use
from socket import *
from My_TCP_callable import *
Everything from each module is imported, and the socket names are clashing (preference is given to the one from My_TCP_callable.
I reproduced this behaviour with two files, test2.py which contained one line, import socket, and test.py which contained
from socket import *
from test2 import *
socket()
A good coding style is to use from ... import * very rarely, and only on modules specifically designed for it.

Python: Print data while waiting for input

Writing a chat program and am looking for the ability for it to print messages that are being received when they are received while the user can enter a message to the other person. Currently the program sends message to other computer then receives the other computer's message and then repeats.
import sys
import socket as so
import platform
from socket import *
import string
import base64
import os
import random
dmi = 0
lmi = 0
host = ""
checkcode = ''.join(random.choice('0123456789QWERTYUIOPLKJHGFDSAZXCVBNMasdfgjhklpoiuytrewqmnzbxvc') for i in range(16))
BLOCK_SIZE = 32
hostl = raw_input("> Input IP of computer message will be sent to: ")
port = 13000
buf = 1024
addr = (host, port)
addrl = (hostl, port)
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)
addr = (host, port)
addrl = (hostl, port)
while dmi == 0:
datal = raw_input("Enter message to send or type 'exit': ")
UDPSock.sendto(datal, addrl)
if datal == "exit":
UDPSock.close()
dmi +=1
(data, addr) = UDPSock.recvfrom(buf)
print "Received message: "+ data
print "Done!"
Don't ask about the un-needed libraries that I have imported, this is a test script.
You need to learn how to use multiple threads (http://www.tutorialspoint.com/python/python_multithreading.htm). One thread waits for user input, while the other receives the messages and prints them.

How to receive data from a socket, process, and send back data in python?

i have the following code:
import socket # Import socket module
import sys
s = socket.socket() # Create a socket object
host = '' # Get local machine name
port = 1234 # Reserve a port for your service.
s.connect((host, port))
while 1:
data = s.recv(1024)
print ' data ' , data
d = data.split('?') # parsing values from server
if len(d) < 2:
# if does not contain ?, do nothing
continue
else:
a = d[0]
b = d[1].replace('\n', '')
# check how a compares to b, and send response accordingly
if (a > b):
s.send('1')
elif (a == b):
s.send('2')
else:
s.send('3')
s.close() # Close the socket when done
Without the processing code I have, it works fine if I just send a random value. But with the code above, I can only parse the first set of line, and then it stops. (I assume it closes the socket or something?)
The data coming from the socket looks like '1 ? 23' or '23 ? 1' , etc. it expects a response that determines how the two numbers relate.
In comparison, if I have this code:
import socket # Import socket module
import sys
s = socket.socket() # Create a socket object
host = '' # Get local machine name
port = 1234 # Reserve a port for your service.
s.connect((host, port))
backlog = ''
while 1:
data = s.recv(1024)
sp = data.split('\n')
if len(sp) < 2:
backlog += data
continue
line = backlog + sp[0]
backlog = sp[1]
data = line
print ' data ' , data
if not data:
break
s.send ('2')
s.close() # Close the socket when done
This code will yield a server response of either 'Correct!' or 'Incorrect...try again!' depending on whether it's right or wrong.
You seem to assume that you always get a full line with each read() call. That is wrong.
You should split your input into lines, and only if you have a full line, you proceed.
backlog = ''
while 1:
data = s.recv(1024)
# do we have a line break?
sp = data.split('\n')
if len(sp) < 2:
# no, we haven't...
backlog += data
continue
# yes, we have.
line = backlog + sp[0] # first part is the now complete line.
backlog = sp[1] # 2nd part is the start of the new line.
print ' line ' , line
d = line.split('?') # parsing values from server
if len(d) < 2:
# if does not contain ?, do nothing
continue
else:
a = int(d[0]) # we want to compare numbers, not strings.
b = int(d[1])
# check how a compares to b, and send response accordingly
if (a > b):
s.send('1')
elif (a == b):
s.send('2')
else:
s.send('3')
Try out what happens now.
Another question which occurs to me is what exactly does the server expect? Really only one byte? Or rather '1\n', '2\n', '3\n'?

Categories

Resources