开发者

Connect to remote host and read data using C#

I have a server that streams data out on a TCP port once you connect to it. You can see this if you telnet 开发者_运维技巧to the TCP port and data starts flowing.

I am looking for an example that will let me connect to an IP address and port and receive the data in a stream in the application.

All examples I can find are with a client-server model with the client sending (which is not what I need) and the server binding to a port on itself and receiving.

I need this to be asynchronous and believe this can be done, but I could do with a good leg up!


If you are using a TcpClient, using GetStream for getting the NetworkStream and then use the stream for reading the data sent by the server. You can always use the stream asynchronously, using BeginRead.

If you are using a plain old Socket, you can use BeginReceive to receive asynchronously once connected.

Either way, as soon as you have a NetworkStream or a Socket object that is bound and connected, there is no difference between the server or the client. You can use the server example of reading in the client code, most often with no (or little) modification.

For an example:

byte[] readBuffer = new byte[1000]; 

{
    TcpClient tcpClient = new TcpClient(serverHost, serverPort);
    NetworkStream stream = tcpClient.GetStream();

    stream.BeginRead(readBuffer, 0, 1000, readHandler, tcpClient);
}

...

byte[] tempBuff = new byte[1000];
int tempBuffSize = 0;

// This is a rough example of reading and handling data
// that is delimited by \r\n. This code most probably is
// missing many edge case handling, so use it only as a starting
// point
void readHandler(IAsyncResult result)
{
    TcpClient tcpClient = (TcpClient)result.AsyncState;
    int dataLen = tcpClient.GetStream().EndRead();

    int currStart = 0;
    int currEnd = -1;

    for (int i = 0; i < dataLen; i++)
    {
        if (readBuffer[i] == '\r' && i < (readBuffer.Length - 1) &&
            readBuffer[i + 1] == '\n')
        {
            // Set the end of the data
            currEnd = i - 1;

            // If we have left overs from previous runs:
            if (tempBuffSize != 0)
            {
                // Allocate enough space for the joined buffer
                byte[] joinedData = new byte[tempBuffSize + (currEnd - currStart + 1)];

                // Get the leftover from the previous read
                Array.Copy(tempBuff, 0, joinedData, 0, tempBuffSize);

                // And add the current read as well
                Array.Copy(readBuffer, currStart, joinedData, tempBuffSize, (currEnd - currStart + 1));

                // Now handle it
                HandleData(joinedData, 0, joinedData.Length);

                // Mark that we don't have any leftovers anymore
                tempBuffSize = 0;
            }
            else
            {               
                // Handle the data, from the start to the end, between delimiter
                HandleData(readBuffer, currStart, currEnd);
            }

            // Set the new start - after our delimiter
            currStart = i + 2;
        }
    }

    // See if we still have any leftovers
    if (currStart < dataLen)
    {
        Array.Copy(readBuffer, currStart, tempBuff, 0, dataLen - currStart);
        tempBuffSize = dataLen - currStart;
    }

    // Set the asynchronous read again
    stream.BeginRead(readBuffer, 0, 1000, readHandler, tcpClient);
}   
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜