0

I am new to Networking and trying to implement a network calculator using python3 where the client's responsibility is to send operands and operators and the server will calculate the result and send it back to the client. Communication is through UDP messages and I am working on client side. Each message is comprised of a header and a payload and they are described as shown in the below figures.

UDP header:

enter image description here

I am familiar with sending string messages using sockets but having a hard-time with how to make a message with both header and payload and how to assign the bits for various attributes or how to generate message/client id's in the header and If there is any way to automatically generate the Id's. Any help or suggestions will be highly appreciated.

Thanks in advance

2
  • Spend some time reading about struct.pack() and struct.unpack() Commented Nov 28, 2022 at 23:14
  • @user3435121 thank you for the comment, I have read up on the struct.pack() for encoding, I see that an integer(4 bytes) can be packed and unpacked, my entire header should be 4 bytes and this should be partitioned into 5 fields any idea on how to proceed with that? the payload can be easily appended as its 4* integers, I am a bit confused on the header part Commented Nov 29, 2022 at 8:06

1 Answer 1

1

I will only do a portion of your homework.
I hope it will help you to find energy to work on missing parts.

import struct
import socket

CPROTO_ECODE_REQUEST, CPROTO_ECODE_SUCCESS, CPROTO_ECODE_FAIL = (0,1,2)

ver = 1  # version of protocol
mid = 0  # initial value
cid = 99 # client Id (arbitrary)

sock = socket.socket( ...) # to be customized

def sendRecv( num1, op, num2):
  global mid
  ocs = ("+", "-", "*", "/").index( op)
  byte0 = ver + (ocs << 3) + (CPROTO_ECODE_REQUEST << 6)
  hdr = struct.pack( "!BBH", byte0, mid, cid)
  parts1 = (b'0000' + num1.encode() + b'0000').split(b'.')
  parts2 = (b'0000' + num2.encode() + b'0000').split(b'.')
  msg = hdr + parts1[0][-4:] + parts1[1][:4] + parts2[0][-4:] + parts2[1][:4]
  
  socket.send( msg)         # send request
  bufr = socket.recv( 512)  # get answer
  # to do:
  #   complete socket_send and socket.recv
  #   unpack bufr into: verr,ecr,opr,value_i, value_f
  #   verify that verr, ecr, opr, are appropriate
  #   combine value_i and value_f into answer
  mid += 1
  return answer

result = sendRecv( '2.47', '+', '46.234')

There are many elements that haven't be specified by your teacher:

  • what should be the byte-ordering on the network (bigEndian or littleEndian)? The above example suppose it's bigEndian but you can easily modify the 'pack' statement to use littleEndian.
  • What should the program do if the received packet header is invalid?
  • What should the program do if there's no answer from server?
  • Payload: how should we interpret "4 most significant digits of fraction"? Does that mean that the value is in ASCII? That's not specified.
  • Payload: assuming the fraction is in ASCII, should it be right-justified or left-justified in the packet?
  • Payload: same question for integer portion.
  • Payload: if the values are in binary, are they signed or unsigned. It will have an affect on the unpacking statement.

In the program above, I assumed that:

  • values are positive and in ASCII (without sign)
  • integer portion is right-justified
  • fractional portion is left justified

Have fun!

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much for the idea, I worked on a bit, It gave me an idea on how to proceed 😁. The assignment is not very clear to me as well, the description was a bit vague, I was given a c implementation of the server and I am trying to understand how its receiving, right now the server is responding to the message request from client and processing the result, although the values are not correct, I am working on it, I will keep you updated 😁. Once again thanks a lot for your suggestion
I have the application working now, I have tried the implementation of "parts1, part2 and header" it was generating a value of "808464432" instead of "0", I have seen some posts on why its happening. I spent some time debugging it but weren't able to get it, so I have used the python inbuilt func of "int.to_bytes" instead at part1 and part2 and I was able to get the correct values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.