0

Im making an application that needs to receive a TCP connection that comes with a request that contains some header data that i need to read and send back with more info later. The issue is that after googling everywhere for days and countless tests it seems the only way to get the Header from a TCP connection is with using sockets specifically Raw sockets and enabling "SocketOptionName.HeaderIncluded" But when using raw sockets i cant find a way to make a stable TCP connection. Only two ways i seem to be able to make a connection is with normal TCP client and with normal sockets (example)`

    private static readonly Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
    private const int BUFFER_SIZE = 2048;
    private const int PORT = 52000;
    private static readonly byte[] buffer = new byte[BUFFER_SIZE];
    private static readonly List<Socket> clientSockets = new List<Socket>();

    public static void ServerMode()
    {
        Console.WriteLine("Setting up server...");
        serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT));
        serverSocket.Listen(0);
        serverSocket.BeginAccept(AcceptCallback, null);
        Console.WriteLine("Server setup complete");
        while (true) { Thread.Sleep(10); }
    }


    private static void AcceptCallback(IAsyncResult AR)
    {
        Socket socket;

        try
        {
            socket = serverSocket.EndAccept(AR);
        }
        catch (ObjectDisposedException) 
        {
            return;
        }

        clientSockets.Add(socket);
        socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
        Console.WriteLine("Client connected, waiting for request...");
        serverSocket.BeginAccept(AcceptCallback, null);
    }

    private static void ReceiveCallback(IAsyncResult AR)
    {
        Socket current = (Socket)AR.AsyncState;
        int received;

        try
        {
            received = current.EndReceive(AR);
        }
        catch (SocketException)
        {
            Console.WriteLine("Client forcefully disconnected");
            // Don't shutdown because the socket may be disposed and its disconnected anyway.
            current.Close();
            clientSockets.Remove(current);
            return;
        }

        byte[] recBuf = new byte[received];
        Array.Copy(buffer, recBuf, received);
        string text = Encoding.ASCII.GetString(recBuf);
        Console.WriteLine("Received Text: " + text);

        current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
    }

`But when running Raw your cant use socket.Listen(); Im hoping someone has experienced anything like this and has a solution, either a way to establish a TCP connection with raw sockets or a way to get the header from a TCP connection. Im constantly baffled by how hard it is to get the god damm header.

2
  • Would it be more elegant to have a pair of threads, one servicing a standard TCP socket, and a second running pcap that extracts the header information you want (from the same packets) then makes it available for when needed later? Commented Aug 4, 2022 at 14:20
  • 1
    You're probably searching in the wrong direction. It's very unlikely that you want to read the TCP header (as the socket layer will handle the TCP stuff for you), but that you need to read an application-protocol-specific header. Such "headers" are just in the data you receive, not in the TCP headers. If you go the raw sockets way, you'll basically have to implement TCP yourself again in C# code. Commented Aug 4, 2022 at 14:20

1 Answer 1

1

... that comes with a request that contains some header ...

You are mixing things up here: TCP has no requests, TCP is only an unstructured stream of bytes. Any semantic of "message", "request" or similar is purely at the application level, i.e. an application protocol which defines a structure semantic on top of the unstructured byte stream. An example for such an application protocol is HTTP which defines a message as having a variable sized header and body and the notion of request and response as specific kinds of messages.

... it seems the only way to get the Header from a TCP connection is with using sockets specifically Raw sockets and enabling "SocketOptionName.HeaderIncluded"

Based on your last question you are not actually looking for a TCP header, but for an application message which contains some header. To cite:

... how to get the TCP header in c#. I know that the messages that I will receive will include two headers, a 16 - byte header and a 48 - byte header.

Given that the TCP header is always 20 bytes you cannot mean the real TCP header here, but this is about some kind of message header for some unknown kind of message format. No raw sockets are needed in this case, but you simple need to read as much bytes as the message/request has and then strip the header from what you've read.

But how much bytes you need read for the request and how to strip the header from the request fully depends on the application protocol. If there is always some first header with 16 bytes, then read 16 bytes from the socket. If there is always another header with 48 bytes read these 48 byte. If these header somehow define how large the rest of the message is, extract this information and read that much bytes.

So the first information you need is to find out, how exactly the protocol is defined, i.e. how the structure of a message or requests is mapped to a stream of bytes. Without this information it is impossible to implement your task.

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

2 Comments

You just might be right, it seems to have i have completely missed this possibility. I have now split the bytes into 3 arrays. The 16 byte header the 48 byte header and the data. To translate the 16 byte header i have the Byte index and Byte length for different values in the header An example would be Byte index = 0 Byte lenght = 1 Field = "Protocol ID" Description X = 70 (‘F’) or Byte index = 4 Byte Lenght = 4 Field = connection ID How would igo about translating this data into usable information? I have currently tried Bitconvert and BinaryReader but cant make it work
@xguysOG: ".... but cant make it work" - I recommend that you start a new question which focuses exactly on this point, i.e. getting specific protocol information from a byte array. This question should include what exactly you want to extract as information, the code you've tried and where you've failed - just stating "can't make it work" is not sufficient.

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.