Getting Response from telnet C# tcpclient - c#

I've been browsing for answers regarding my concern but I can't find concrete answers or at least clear thoughts on getting a response from Telnet connection. Here is my code:
TcpClient vpnMI = new TcpClient("127.0.0.1", 7505);
String message = "hold release\n";
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
NetworkStream stream = vpnMI.GetStream();
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent {0}", message);
data = new Byte[256];
MemoryStream memoryStream = new MemoryStream();
String responseData = String.Empty;
Int32 bytes = 0;
do
{
bytes = stream.Read(data, 0, data.Length);
memoryStream.Write(data, 0, bytes);
}
while (stream.DataAvailable);
responseData = System.Text.Encoding.ASCII.GetString(memoryStream.ToArray());
Console.WriteLine("Received: {0}", responseData);
// Close everything.
stream.Close();
vpnMI.Close();
But I can only get the response before the "hold release" was sent even though there is a response after.
Thank you in advance for the response.

I am using this piece of code, you can take a look if this help:
public async Task<string> SendMessageAsync(string host, int port, string message, string encoding = "utf-8")
{
using (var tcpClient = new TcpClient())
{
//connect
await tcpClient.ConnectAsync(host, port);
using (NetworkStream networkStream = tcpClient.GetStream())
{
//write message to stream
var enc = Encoding.GetEncoding(encoding);
var bytes = enc.GetBytes(message);
await networkStream.WriteAsync(bytes, 0, bytes.Length);
//read response from stream
var buffer = new byte[READ_BUFFER_SIZE];
using (var ms = new MemoryStream())
{
//read all bytes to ms
while (true)
{
int byteCount = await networkStream.ReadAsync(buffer, 0, READ_BUFFER_SIZE);
ms.Write(buffer, 0, byteCount);
if (byteCount < READ_BUFFER_SIZE)
{
break;
}
}
//convert ms to string
ms.Seek(0, SeekOrigin.Begin);
using (StreamReader sr = new StreamReader(ms, enc))
{
var result = await sr.ReadToEndAsync();
return result;
}
}
}
}
}
networkStream.ReadAsync() returns the count of bytes that actually read from stream, if this count is less than the count you're trying to read, that's the last part.

Related

How to attach a PDF from a ConnectStream to an Email

I am calling a WebAPI that returns a PDF in a ConnectStream. I write that ConnectStream to a file and then read it back in to a memorystream and I can attach it to an email. How can I accomplish the same thing without the IO overhead?
System.Net.HttpWebResponse webResponse = (System.Net.HttpWebResponse)webRequest.GetResponse();
System.IO.Stream stream = webResponse.GetResponseStream();
System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.Default);
string finalPath = System.IO.Path.Combine(outputPath, $"{startDate:yyyy-MM-dd}_{endDate:yyyy-MM-dd}.pdf");
System.IO.Stream fileStream = System.IO.File.OpenWrite(finalPath);
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fileStream, Encoding.Default))
{
sw.Write(reader.ReadToEnd());
sw.Flush();
sw.Close();
}
using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(finalPath)))
{
using (MailMessage mailMessage = new MailMessage())
{
mailMessage.From = new MailAddress("noreply#somedomain.com");
mailMessage.To.Add("someone#somedomain.com");
mailMessage.Attachments.Add(new Attachment(ms, new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Application.Pdf)));
SmtpClient smtpClient = new SmtpClient() { DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.SpecifiedPickupDirectory, PickupDirectoryLocation = outputPath };
smtpClient.Send(mailMessage);
}
}
First, the request stream is a one-way read only stream and cannot be passed to most methods that allow a stream, so you need to read it into something you can manipulate:
public byte[] ReadStreamBinary(Stream stream, int bufferSize)
{
using (var ms = new MemoryStream())
{
var buffer = CreateBuffer(bufferSize);
var finished = false;
while (!finished)
{
buffer.Initialize();
var bytes = stream.Read(buffer, 0, buffer.Length);
if (bytes > 0)
{
ms.Write(buffer, 0, bytes);
}
else
{
finished = true;
}
}
return ms.ToArray();
}
}
Then you can just create your MemoryStream from this array of bytes.
Since the default internal buffer for a stream is 4k, I almost always use that as my buffer size (4096). In your case, it may be easier to just modify the method to return the MemoryStream directly.
If you decide to return the stream, you'll need to remove the using (so the stream won't get closed/disposed) and return the stream pointer to the beginning.
public MemoryStream ReadStreamBinary(Stream stream, int bufferSize)
{
var ms = new MemoryStream();
var buffer = CreateBuffer(bufferSize);
var finished = false;
while (!finished)
{
buffer.Initialize();
var bytes = stream.Read(buffer, 0, buffer.Length);
if (bytes > 0)
{
ms.Write(buffer, 0, bytes);
}
else
{
finished = true;
}
}
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
Just remember to close/dispose of the stream in the calling method.
Oops. almost forgot to include the CreateBuffer code, just put this anywhere in your class:
public static Func<int, byte[]> CreateBuffer = x => (byte[])Array.CreateInstance(typeof(byte), x);

c# Tcp client transfer file with sslStream

I try to send a file with an sslStream of tcp client. File is about 250kb.
When i don't write dataLength to stream, server closes the connection i thing because of max receive buffer size. When i write into stream the dataLength, i have no exception but server has an error of type (connection closed gracefully). One reason is that, because the Tcp client close event, the server
can not receive the data that i have sent; Here is my code. Server code is missing that i know that it has be writen in delphi with indy sockets library
Here is my code
TcpClient sendClient = new TcpClient(serverName, port);
LingerOption lingerOption = new LingerOption(true, 20);
sendClient.LingerState = lingerOption;
using (SslStream sendStream = new SslStream(sendClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
{
try
{
sendStream.AuthenticateAsClient(serverName, null, SslProtocols.Ssl2, true);
sendStream.Write(Encoding.UTF8.GetBytes("Login\r\n" + username + "\r\n" + password + "\r\n"));
sendStream.Flush();
int bytesResp = -1;
byte[] buffer = new byte[1024];
bytesResp = sendStream.Read(buffer, 0, buffer.Length);
string response = Encoding.UTF8.GetString(buffer, 0, bytesResp);
if (response.Trim() == "OK")
{
sendStream.Write(Encoding.ASCII.GetBytes("Send\r\n"));
FileStream inputStream = File.OpenRead(filePath);
FileInfo f = new FileInfo(filePath);
int size = unchecked((int)f.Length);
byte[] byteSize = Encoding.ASCII.GetBytes(size.ToString());
sendStream.Write(byteSize);
sendStream.Write(Encoding.ASCII.GetBytes("\r\n"));
sendStream.Write(Encoding.ASCII.GetBytes(fileName + "\r\n"));
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
long sum = 0;
int count = 0;
byte[] data = new byte[1024];
while (sum < size)
{
count = fs.Read(data, 0, data.Length);
sendStream.Write(data, 0, count);
sum += count;
Array.Clear(data, 0, data.Length);
}
sendStream.Flush();
}
sendStream.Write(Encoding.UTF8.GetBytes("\r\n"));
sendStream.Write(Encoding.UTF8.GetBytes("Quit\r\n"));
}
MessageBox.Show("end the procedure");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
if (sendClient.Client.Connected)
{
sendClient.Client.Disconnect(false);
sendClient.Client.Dispose();
}
}
I'm not sure if it will be of help but I had a similar issue with using(){} which for some reason it closed the sslstream.
So potentially remove
using (SslStream sendStream = new SslStream(sendClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null)){}
into
SslStream sendStream = new SslStream(sendClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);

Too many bytes received on my server socket

I have a listening socket on my UWP device.
This the code for that:
List<byte> requestInBytes = new List<byte>();
using (IInputStream input = args.Socket.InputStream)
{
byte[] data = new byte[BufferSize];
IBuffer buffer = data.AsBuffer();
uint dataRead = BufferSize;
while (dataRead == BufferSize)
{
await input.ReadAsync(buffer, BufferSize, InputStreamOptions.Partial);
requestInBytes.AddRange(data);
dataRead = buffer.Length;
}
}
var ct = requestInBytes.Count;
The count returned on that is:
630784
On my client Winform desktop I am sending the byte array as follows:
using (TcpClient clientSocket = new TcpClient())
{
await clientSocket.ConnectAsync(GeneralTags.RASPBERRY_PI_IP_ADDRESS, GeneralTags.RASPBERRY_PI_PORT);
using (NetworkStream serverStream = clientSocket.GetStream())
{
List<byte> requestInBytes = new List<byte>();
serverStream.Write(byteArray, 0, byteArray.Length);
serverStream.Flush();
}
}
The count of what I am sending is:
626840
Why are there more bytes received into my server?
The problem is that you add the entire buffer array data regardless of the actual number of received bytes.
Change the line
requestInBytes.AddRange(data)
to
requestInBytes.AddRange(data.Take(buffer.Length))

Changing FileStream Write encoding type

This is my code :
public static string DownloadFile(string FtpUrl, string FileNameToDownload,
string userName, string password, string tempDirPath)
{
string ResponseDescription = "";
string PureFileName = new FileInfo(FileNameToDownload).Name;
string DownloadedFilePath = tempDirPath + "/" + PureFileName;
string downloadUrl = String.Format("{0}/{1}", FtpUrl, FileNameToDownload);
FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create(downloadUrl);
req.Method = WebRequestMethods.Ftp.DownloadFile;
req.Credentials = new NetworkCredential(userName, password);
req.UseBinary = true;
req.Proxy = null;
try
{
FtpWebResponse response = (FtpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
byte[] buffer = new byte[2048];
FileStream fs = new FileStream(DownloadedFilePath, FileMode.Create);
int ReadCount = stream.Read(buffer, 0, buffer.Length);
while (ReadCount > 0)
{
fs.Write(buffer, 0, ReadCount);
ReadCount = stream.Read(buffer, 0, buffer.Length);
}
ResponseDescription = response.StatusDescription;
fs.Close();
stream.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return ResponseDescription;
}
}
This code Downloads a file from a ftp server and write it to a specific path in server.
but the encoding of the saved file is not UTF-8.
I want to change the encoding type of the file to UTF-8.
Do I must use StreamReader ?
How Can I modify that code?
In theory, the below should work, but it depends or whether the responsestream can work together with the streamreader.
Writing with a different encoding is easy, you can simply use a streamwriter (based on textwriter) instead of a filestream. However, you can't write the bytes directly, since you have to write the properly formatted text. For that, the bytes have to be converted to text (Char buffer) with the proper original encoding.
char[] buffer = new char[2048]; //or 1024 if you want to keep the same block size
using (var reader = new StreamReader(stream, Encoding.Unicode)) // <= Or whatever encoding the orignal is
{
using (var tw = new StreamWriter(DownloadedFilePath, false, Encoding.UTF8)) //streamwriter instead of filestream
{
while (true)
{
int ReadCount = reader.Read(buffer, 0, buffer.Length);
if (ReadCount == 0) break;
tw.Write(buffer, 0, ReadCount);
}
ResponseDescription = response.StatusDescription;
stream.Close();
tw.Close();
}
}
If the streamreader gives problems, you can also download the bytes first, and use a streamreader on the already downloaded bytes.
You can wrap it in StreaWriter:
try
{
FtpWebResponse response = (FtpWebResponse)req.GetResponse();
Stream stream = response.GetResponseStream();
byte[] buffer = new byte[2048];
var sw = new StreamWriter( new FileStream(DownloadedFilePath, FileMode.Create),
Encoding.UTF8);
int ReadCount = stream.Read(buffer, 0, buffer.Length);
while (ReadCount > 0)
{
sw.Write(buffer, 0, ReadCount);
ReadCount = stream.Read(buffer, 0, buffer.Length);
}
ResponseDescription = response.StatusDescription;
sw.Close();
stream.Close();
}
I hope it will help
You have a look here :https://stackoverflow.com/ answer

Read Http Request into Byte array

I'm developing a web page that needs to take an HTTP Post Request and read it into a byte array for further processing. I'm kind of stuck on how to do this, and I'm stumped on what is the best way to accomplish. Here is my code so far:
public override void ProcessRequest(HttpContext curContext)
{
if (curContext != null)
{
int totalBytes = curContext.Request.TotalBytes;
string encoding = curContext.Request.ContentEncoding.ToString();
int reqLength = curContext.Request.ContentLength;
long inputLength = curContext.Request.InputStream.Length;
Stream str = curContext.Request.InputStream;
}
}
I'm checking the length of the request and its total bytes which equals 128. Now do I just need to use a Stream object to get it into byte[] format? Am I going in the right direction? Not sure how to proceed. Any advice would be great. I need to get the entire HTTP request into byte[] field.
Thanks!
The simplest way is to copy it to a MemoryStream - then call ToArray if you need to.
If you're using .NET 4, that's really easy:
MemoryStream ms = new MemoryStream();
curContext.Request.InputStream.CopyTo(ms);
// If you need it...
byte[] data = ms.ToArray();
EDIT: If you're not using .NET 4, you can create your own implementation of CopyTo. Here's a version which acts as an extension method:
public static void CopyTo(this Stream source, Stream destination)
{
// TODO: Argument validation
byte[] buffer = new byte[16384]; // For example...
int bytesRead;
while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
{
destination.Write(buffer, 0, bytesRead);
}
}
You can just use WebClient for that...
WebClient c = new WebClient();
byte [] responseData = c.DownloadData(..)
Where .. is the URL address for the data.
I use MemoryStream and Response.GetResponseStream().CopyTo(stream)
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
myRequest.Method = "GET";
WebResponse myResponse = myRequest.GetResponse();
MemoryStream ms = new MemoryStream();
myResponse.GetResponseStream().CopyTo(ms);
byte[] data = ms.ToArray();
I have a function that does it, by sending in the response stream:
private byte[] ReadFully(Stream input)
{
try
{
int bytesBuffer = 1024;
byte[] buffer = new byte[bytesBuffer];
using (MemoryStream ms = new MemoryStream())
{
int readBytes;
while ((readBytes = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, readBytes);
}
return ms.ToArray();
}
}
catch (Exception ex)
{
// Exception handling here: Response.Write("Ex.: " + ex.Message);
}
}
Since you have Stream str = curContext.Request.InputStream;, you could then just do:
byte[] bytes = ReadFully(str);
If you had done this:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(someUri);
req.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
You would call it this way:
byte[] bytes = ReadFully(resp.GetResponseStream());
class WebFetch
{
static void Main(string[] args)
{
// used to build entire input
StringBuilder sb = new StringBuilder();
// used on each read operation
byte[] buf = new byte[8192];
// prepare the web page we will be asking for
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(#"http://www.google.com/search?q=google");
// execute the request
HttpWebResponse response = (HttpWebResponse)
request.GetResponse();
// we will read data via the response stream
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
do
{
// fill the buffer with data
count = resStream.Read(buf, 0, buf.Length);
// make sure we read some data
if (count != 0)
{
// translate from bytes to ASCII text
tempString = Encoding.ASCII.GetString(buf, 0, count);
// continue building the string
sb.Append(tempString);
}
}
while (count > 0); // any more data to read?
// print out page source
Console.WriteLine(sb.ToString());
Console.Read();
}
}
For all those cases when your context.Request.ContentLength is greather than zero, you can simply do:
byte[] contentBytes = context.Request.BinaryRead(context.Request.ContentLength);

Categories