1

Hi all,I have the server ip and port number,and then I want to use Socket TcpClient object to connet the server to send and receive data,But I don't konw how to customize the tcp-ip datagram.

Here is the describe of packet

name                  bit         datatype
sync_tag              16          uint(16)    const:0xAA 0x55
version               8           uint(8)     const:0x01
packet_length         16          uint(16)    ?
payload_id            8           uint(8)     0x01,0x02,0x03,0x04...(now it is 0x01)
for(int i=0;i<length-8;i++){
payload_data          8           byte(1)      ?
}                                   
CRC16                 16          uint(16)    ?

packet_length:from the first byte of sync_tag to the last byte CRC16 payload_data :Now the structure like below

syntax           bit      datatype   
username         264      char(33)
password         264      char(33)

Is this any way to konw what is the "length-8" and and how to calculate the packet_length? Finally I will send byte[] by using TcpClient and NetwordStream?

    >here is the codes I attempt to write
    >I don't know how to send the packet
    [1]: chinafilm.org.cn/uploads/soft/140117/2_1140448191.pdf  
    public static void TestTcpClient()
    {
        TcpClient client = new TcpClient("58.62.144.227", 18080);
        NetworkStream stream = client.GetStream();
        client.LingerState = new LingerOption(true, 30);
        if (!client.Connected)
        {
            Console.WriteLine("Connect Error!");
            return;
        }
        byte[] buffer = new byte[1024];
        //I don't konw what is packet_length,so packetlength is a test sample
        byte[] packetlength = new byte[2];
        //Like packetlength,It is a test sample;
        byte payloadData = byte.MinValue;
        //CRC16 algorithm,I can find some example 
        byte[] crc16 = new byte[2];
        buffer[0] = 0xAA; //sync_tag;
        buffer[1] = 0x55;
        buffer[2] = 0x01; //versin
        buffer[3] = packetlength[0]; //packet_length;
        buffer[4] = packetlength[1];
        buffer[5] = 0x01; //payload_id : If I use the username and password,It is 0x01
        buffer[6] = payloadData;//Contains username and password
        buffer[7] = crc16[0];
        buffer[8] = crc16[1];
        stream.Write(buffer, 0, buffer.Length);
        // Buffer to store the response bytes.
        byte[] data = new Byte[256];
        // String to store the response ASCII representation.
        String responseData = String.Empty;
        // Read the first batch of the TcpServer response bytes.
        Int32 bytes = stream.Read(data, 0, data.Length);
        responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
        Console.WriteLine("Received: {0}", responseData);
        // Close everything.
        stream.Close();
        client.Close();
    }
rival
  • 13
  • 4
  • It would be better if you start with your draft implementation, so we can know your current progress so far. – tia Jan 13 '15 at 07:02
  • A side question: is it actually correct to say "tcp datagram"? – zerkms Jan 13 '15 at 07:04
  • No, there's no such thing as a "TCP datagram". – Peter Duniho Jan 13 '15 at 07:20
  • Who is defining a "packet"? Is this just the abstract description of the data, or are you required to comply with a predefined network protocol? I agree with tia, that you should write some code, make an attempt, and then ask your question. Show us what research you've already done, and where you got stuck. – Peter Duniho Jan 13 '15 at 07:23
  • @PeterDuniho I edited my question,but whatever I send to the server,I receive 0 – rival Jan 14 '15 at 13:01
  • @zerkms Please bear me with my terrible english. – rival Jan 14 '15 at 13:11
  • @tia In simple terms,I don’t kown how to customize packet and send the data to the server,I edited some codes in the question... – rival Jan 14 '15 at 13:14
  • @PeterDuniho I don't think I must to comply with a predefined network protocol,I Just need to use the correct packet to send data.But,How to calculate the "packet_length" and where should I put the "packet_length" in a byte[]? – rival Jan 14 '15 at 15:03
  • Based on your edit, I'd disagree with your statement that you don't need to comply with a predefined network protocol. It seems you are communicating with a third-party server, which has defined the protocol to which you must adhere. I don't see anything in your code example that involves `username` or `password`. However, it seems likely that the most helpful advice you can use right now is for me to suggest you look at the [`BitConverter`](http://msdn.microsoft.com/en-us/library/system.bitconverter(v=vs.110).aspx) class, which provides methods to convert between primitive types and `byte[]` – Peter Duniho Jan 14 '15 at 18:20
  • @PeterDuniho Yes,I will use the third-party server,Here is the pdf file they provide me http://www.chinafilm.org.cn/uploads/soft/140117/2_1140448191.pdf But it is written in Chinese. Another company designed the server software,they don't not want to reveal too many details,When I use TcpClient connet the server,It‘s connected,But I don’t konw how to use NetworkStream object to write data... – rival Jan 15 '15 at 02:22
  • I can't read Chinese, nor would I download something from an un-vetted third-party web site in any case. You can use `BinaryWriter` or (as I already mentioned) `BitConverter` to format data as bytes to transmit. You will need to know the details of the protocol though; if the hosts of the server aren't sharing those details, it may be because they don't want you interacting with their server at all. If they do want you to interact with their server, you should have no problems getting technical support help from them with respect to the exact details of the protocol. – Peter Duniho Jan 15 '15 at 02:34
  • @PeterDuniho Ok,thank you very much. Actually, there are some other reasons that We can't get fully supported. I'll try more ways to send data. – rival Jan 15 '15 at 03:51
  • @PeterDuniho thank you,I have finished the job! Eventually I get technical support ! – rival Jan 23 '15 at 06:02

1 Answers1

1

You can use MemoryStream along with a BinaryWriter to easily construct the package

    MemoryStream bufferStream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(bufferStream);
    writer.Write(new byte[] { 0xAA, 0x55, 0x01 });
    writer.Write((ushort)66 + 8); // size of username/password, plus all overheads
    writer.Write((byte) 0x01);
    writer.Write("foouser".PadRight(33, '\0')) // Padding to 33 characters
    writer.Write("foooassword".PadRight(33, '\0')) // Padding to 33 characters
    // calculate CRC
    ushort crc16 = 999;
    writer.Write(crc16);
    // get result
    byte[] result = bufferStream.ToArray();

More info about padding : C# padding string with n bytes and writing it out

For CRC, you might try this NuGet package, though I never used it.

Community
  • 1
  • 1
tia
  • 9,518
  • 1
  • 30
  • 44