TCP Client To Server Command Header?

I would like to send, receive string messages and transfer text files between a Tcp client and server. Using one TCP connection and port I would like to send 'command header' preceeding the string message or file transfer etc. The 'command header' would instruct the server how to process the following data.

[sending file]
              (actual info)     (command)
Client --->  file_data  -->  'FILE' --> Server (handles data accordingly)

[sending message]
              (actual info)    (command)
Client -->  message -->  'MSG'  -->  (handles data accordingly)  

[Combo]
               (actual info)  (command)  (actual info)  (command)
Client -->  file_data  -->  'FILE' -->  message -->  'MSG'  -->  (handles data accordingly)  

pointemanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

 
_Katka_Commented:
Hi, you can always have two servers, one for handling binary files, and one for handling messages.

regards,
Kate
0
 
Keego7237Commented:
Just dedicate the first 3 bytes of every packet as your control information.

Enum type {FILE, MSG, BOTH};
byte 0 = type;
byte 1 = number of bytes to read given the type, if type == both then this is for the FILE
byte 2 = number of MSG bytes to read if type == BOTH

strip out the first 3 bytes of the packet and use that information to figure out how to deal with the rest of the bytes
0
 
pointemanAuthor Commented:
Yes, I agree. Not sure how to build the sending packet and unpack the receiving packet.
Q. Got any code examples?
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
Keego7237Commented:
Ok not sure if this is the best/most efficient way of doing things, but I grabbed the relevant code from a simple game I made. The ToByteArray function shows how to put things in byte array for sending. The rest of the code receives and parses the data.



//to send the data
socket.Send(byteData);



        public byte[] ToByteArray() {
            byte[] pktType = { (byte)type };
            byte[] sentTurn = BitConverter.GetBytes(actionGameTurn);
            byte[] byteCount = { (byte)(PacketManager.PacketDataOverhead + byteData.Length) };
            byte[] dataArray = new byte[PacketManager.PacketDataOverhead + byteData.Length];

            byteCount.CopyTo(dataArray, 0);
            pktType.CopyTo(dataArray, PacketManager.byteCountOverhead);
            sentTurn.CopyTo(dataArray, PacketManager.byteCountOverhead + PacketManager.packetTypeOverhead);
            byteData.CopyTo(dataArray, PacketManager.PacketDataOverhead);
            return dataArray;
        }



// in your ondatareceive function (if they are asynchronous sockets)
SocketState receivedSocketState = (SocketState)asyn.AsyncState;
                int bytesReceived = 0;
                bytesReceived = receivedSocketState.socket.EndReceive(asyn);
                Socket sock = receivedSocketState.socket;

                byte[] data = new byte[bytesReceived];
                for(int i=0; i<bytesReceived; i++){
                    data[i] = receivedSocketState.dataBuffer[i];
                }

                WaitForData(receivedSocketState.socket);
                packetManager.handleNewData(data, bytesReceived, sock);




public void handleNewData(byte[] dataArray, int bytesReceived, Socket sock) {
            if (bytesReceived == 0)
                return;
            int bytesRead = 0;
            // if this is the first packet or the last received stream ended a packet
readLoop:   if (currentPacketStream == null) {
                currentPacketStream = new byte[dataArray[bytesRead]];
                currentPacketStream[0] = dataArray[bytesRead++];
                currentPacketByteCount = 1;
            }
            while (bytesRead < bytesReceived && currentPacketByteCount < currentPacketStream[0]) {
                currentPacketStream[currentPacketByteCount++] = dataArray[bytesRead++];
            }
            // if packet is complete
            if (currentPacketByteCount == currentPacketStream[0]) {
                handleNewPacket(Packet.GetPacket(currentPacketStream, sock));
                currentPacketStream = null;
                currentPacketByteCount = 0;
            }
            // if more data still in the received bytes
            if (bytesRead < bytesReceived)
                goto readLoop;
        }



Packet GetPacket(byte[] arrBytes, Socket socket) {
            byte totalBytes = arrBytes[0];
            int sentTurn = BitConverter.ToInt32(arrBytes, 2);
            Packet pkt = new Packet((PacketType)arrBytes[1], sentTurn);
            pkt.sentFromSocket = socket;
            pkt.byteData = new byte[totalBytes - 6];

            for (int i = 0; i < pkt.byteData.Length; i++) {
                pkt.byteData[i] = arrBytes[i + 6];
            }
            return pkt;
        }
0

Experts Exchange Solution brought to you by ConnectWise

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
 
Keego7237Commented:
Ok that may be a little hard to follow so here's a more condensed version of how to stick the header in what your sending.
        enum PType { MSG, FILE, BOTH };

        void run() {
            socket.send(MSGByteArray("msg"));
        }

        public byte[] MSGByteArray(String message) {
            // 1 byte for type, 1 byte for message length, then space to store the message
            // assumes the message always less than 256 bytes
            int totalLength = 2 + message.Length;
            byte[] dataArray = new byte[totalLength];

            dataArray[0] = (byte)PType.MSG;
            dataArray[1] = (byte)message.Length;

            byte[] messageByteArray = System.Text.Encoding.ASCII.GetBytes(message);

            messageByteArray.CopyTo(dataArray, 2);

            return dataArray;
        }

        public void handleNewPacket(byte[] dataArray) {
            PType type = (PType)dataArray[0];
            byte contentLength = dataArray[1];
            if (type == PType.MSG) {
                //convert remaining dataArray to string
            }
            else if (type == PType.FILE) {
                //convert remaining dataArray to file
            }
            else if (type == PType.BOTH) {
                byte fileLength = dataArray[2];
                //convert contentLength bytes of dataArray to string
                //convert fileLength bytes of dataArray to file
            }
        }

Open in new window

0
 
pointemanAuthor Commented:
Thanks...
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.