title: struct.error: bad char in struct format
body: <p>I have a problem with a little server-client assignment in python 2.7.</p>
  
  <p>The client can send 5 types of requests to the server:</p>
  
  <ol>
  <li>get the server's ip</li>
  <li>get contents of a directory on the server</li>
  <li>run cmd command on the server and get the output</li>
  <li>open a calculator on the server</li>
  <li>disconnect</li>
  </ol>
  
  <p>basically, this is the error I get:</p>
  
  <pre><code>line 19, in server
      data_size = calcsize(client_structs) - 3
  
  struct.error: bad char in struct format
  </code></pre>
  
  <p>Would appreciate explanation about this error + how to solve it.</p>
  
  <p>server code:</p>
  
  <pre><code>__author__ = 'eyal'
  
  from struct import pack, unpack, calcsize
  import socket
  from os import listdir
  from subprocess import check_output, call
  
  
  def server():
      ser_soc = socket.socket()
      ser_soc.bind(("0.0.0.0", 8080))
      ser_soc.listen(1)
      while True:
          accept_flag = raw_input("Would you like to wait for a client? (y/n) ")
          if accept_flag == "y":
              client_soc, client_address = ser_soc.accept()
              while True:
                  client_structs = client_soc.recv(1024)
                  data_size = calcsize(client_structs) - 3
                  data_str = 'c' * data_size
                  unpacked_data = unpack("BH" + data_str, client_structs)
                  if unpacked_data[0] == 1:
                      ip = socket.gethostbyname(socket.gethostname())
                      ip_data = 'c' * len(ip)
                      to_send = pack("BH" + str(len(ip)) + ip_data, unpacked_data[0], len(ip), ip)
                  elif unpacked_data[0] == 2:
                      content = listdir(str(unpacked_data[2]))
                      content_str = "\r\n".join(content)
                      content_data = 'c' * len(content_str)
                      to_send = pack("BH" + str(len(content_str)) + content_data, unpacked_data[0],
                                     len(content_str), content_str)
                  elif unpacked_data[0] == 3:
                      command = str(unpacked_data[2:]).split()
                      output = check_output(command)
                      message_data = 'c' * len(output)
                      to_send = pack("BH" + message_data, unpacked_data[0], len(output), output)
                  elif unpacked_data[0] == 4:
                      call("gnome-calculator")
                      msg_data = 'c' * len("The calculator is open.")
                      to_send = pack("BH" + msg_data, unpacked_data[0], len("The calculator is open."),
                                     "The calculator is open.")
                  elif unpacked_data[0] == 5:
                      client_soc.close()
                      break
                  else:
                      to_send = pack("BH" + 'c' * len("invalid message type, try again"),
                                     unpacked_data[0], len("invalid message type, try again"),
                                     "invalid message type, try again")
                  if unpacked_data[0] != 5:
                      client_soc.send(to_send)
          else:
              break
      ser_soc.close()
  
  
  def main():
      server()
  
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>client code:</p>
  
  <pre><code>__author__ = 'eyal'
  
  
  from struct import pack, unpack, calcsize
  import socket
  
  
  def client():
      my_soc = socket.socket()
      my_soc.connect(("127.0.0.1", 8080))
      while True:
          send_flag = raw_input("Would you like to send the server a request? (y/n) ")
          if send_flag == "y":
              msg_code = input("What type of request would you like to send?\n"
                               "1. Get the server's IP address.\n"
                               "2. Get content of a directory on the server.\n"
                               "3. Run a terminal command on the server and get the output.\n"
                               "4. Open a calculator on the server.\n"
                               "5. Disconnect from the server.\n"
                               "Your choice: ")
              if msg_code == 1 or msg_code == 4 or msg_code == 5:
                  to_send = pack("BH", msg_code, 0)
              elif msg_code == 2:
                  path = raw_input("Enter path of wanted directory to get content of: ")
                  to_send = pack("BH" + 'c' * len(path), msg_code, len(path), path)
              elif msg_code == 3:
                  command = raw_input("Enter the wanted terminal command, including arguments: ")
                  to_send = pack("BH" + 'c' * len(command), msg_code, len(command), command)
              else:
                  print "Invalid message code, try again\n"
  
              if 1 &lt;= msg_code &lt;= 5:
                  my_soc.send(to_send)
          else:
              break
      data = my_soc.recv(1024)
      unpacked_data = unpack("BH" + 'c' * (calcsize(data) - 3), data)
      print "The server's response to your type-" + str(msg_code) + " request:"
      print unpacked_data[2]
      my_soc.close()
  
  
  def main():
      client()
  
  
  if __name__ == "__main__":
      main()
  </code></pre>