socket programming in python doubts
Question: i am having trouble and a lot of questions about socket programming attached
code below ( all parts have been taken from the and written together) i am
trying to send mouse data to the client ,howver getting the error:

    
    
    Traceback (most recent call last):
      File "srvr.py", line 29, in <module>
        serv.sendall(status)
      File "/usr/lib/python2.7/socket.py", line 224, in meth
        return getattr(self._sock,name)(*args)
    TypeError: must be string or buffer, not int
    

Questions: 1.how do we send data over sockets other then strings or
specifically without the .send("...") statement .continously changing data??
2.what things should be kept in mind when sending stream of data?? 3.code
written here is a mess, would gladly appreciate help to teach some code sense
into me

Thank YOu

Code: server side:

    
    
    from socket import *      #import the socket library
    ##let's set up some constants
    HOST = ''    #we are the host
    PORT = 29876    #arbitrary port not currently in use
    ADDR = (HOST,PORT)    #we need a tuple for the address
    BUFSIZE = 4096    #reasonably sized buffer for data
    
    ## now we create a new socket object (serv)
    ## see the python docs for more information on the socket types/flags
    serv = socket( AF_INET,SOCK_STREAM)    
    
    ##bind our socket to the address
    serv.bind((ADDR))    #the double parens are to create a tuple with one element
    serv.listen(5) 
    print 'listening...'
    
    conn,addr = serv.accept() #accept the connection
    print '...connected!'
    mouse = file('/dev/input/mouse0')  
    while True:  
        status, dx, dy = tuple(ord(c) for c in mouse.read(3))  
    
        def to_signed(n):  
            return n - ((0x80 & n) << 1)  
    
        dx = to_signed(dx)  
        dy = to_signed(dy)  
        conn.send(status)
    conn.close()
    

client:

    
    
    ##client.py
    from socket import *
    
    HOST = 'localhost'
    PORT = 29876    #our port from before
    ADDR = (HOST,PORT)
    BUFSIZE = 4096
    
    cli = socket( AF_INET,SOCK_STREAM)
    cli.connect((ADDR))
    data = cli.recv(BUFSIZE)
    while data != '':
        print data
    
    cli.close()
    


Answer: While transferring data over network, it is very usual to pack it according to
the big-endian byte order. Even though you have only three separates bytes at
a time, and thus byte ordering doesn't matter, I still prefer to pack and
unpack simply because it is a common way to communicate. Also, a common thing
to do, when receiving network data, is to check whether you actually received
the amount you were expecting, otherwise you have to request for more data.
For simplicity, consider the following function for that:

    
    
    def recv(sock, size):
        data = ''
        to_receive = size
        while to_receive > 0:
            data += sock.recv(to_receive)
            to_receive = size - len(data)
        return data
    

Now, what is lacking in your code is a common protocol. The client is acting
as a receiver of raw meaningless data. Instead, it should be acting as a
receiver of triplets. Besides that, I suggest to let the client request how
many triplets he wants. Taking this into consideration, that is how I would
change your client code to:

    
    
    import sys
    import socket
    import struct
    
    serv_host = ''
    serv_port = 29876
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((serv_host, serv_port))
    
    # Tell the server how many triplets I want.
    amount = int(sys.argv[1])
    s.sendall(struct.pack('!i', amount))
    pack_size = struct.calcsize('!bbb')
    while amount:
        status, dx, dy = struct.unpack('!bbb', recv(s, pack_size))
        print status, dx, dy
        amount -= 1
    
    s.close()
    

Now the server also needs to respect this newly imposed protocol. Note that a
negative value effectively makes the client receive infinite triplets, that is
intentional. Here is the modified server:

    
    
    import socket
    import struct
    
    def to_signed(n):
        return n - ((0x80 & n) << 1)
    
    mouse = open('/dev/input/mouse0')
    
    host = ''
    port = 29876
    backlog = 5
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((host, port))
    s.listen(backlog)
    print 'Listening'
    while True:
        client, address = s.accept()
    
        # Obtain the number of triplets the client wants.
        amount = struct.unpack('!i', recv(client, 4))[0]
        while amount: # Send the triplets as they become available.
            status, dx, dy = map(ord, mouse.read(3))
            dx, dy = to_signed(dx), to_signed(dy)
            print status, dx, dy
            client.sendall(struct.pack('!bbb', status, dx, dy))
            amount -= 1
    
        client.close()
    

