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);
}
精彩评论