currently i'm facing issue while creating file, i'm trying to write text contents using streamWriter class but i'm not getting expected answer..
Below is my example code :-
My c# code looks like :-
public void ProcessRequest(HttpContext context)
{
// Create a connexion to the Remote Server to redirect all requests
RemoteServer server = new RemoteServer(context);
// Create a request with same data in navigator request
HttpWebRequest request = server.GetRequest();
// Send the request to the remote server and return the response
HttpWebResponse response = server.GetResponse(request);
context.Response.AddHeader("Content-Disposition", "attachment; filename=playlist.m3u8");
context.Response.ContentType = response.ContentType;
Stream receiveStream = response.GetResponseStream();
var buff = new byte[1024];
int bytes = 0;
string token = Guid.NewGuid().ToString();
while ((bytes = receiveStream.Read(buff, 0, 1024)) > 0)
{
//Write the stream directly to the client
context.Response.OutputStream.Write(buff, 0, bytes);
context.Response.Write("&token="+token);
}
//close streams
response.Close();
context.Response.End();
}
output of above code looks like :-
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=20776,CODECS="avc1.66.41",RESOLUTION=320x240
chunk.m3u8?nimblesessionid=62
&token=42712adc-f932-43c7-b282-69cf349941da
But my expected output is :-
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=20776,CODECS="avc1.66.41",RESOLUTION=320x240
chunk.m3u8?nimblesessionid=62&token=42712adc-f932-43c7-b282-69cf349941da
I just wanted that token param in same line instead of new line..
Thank you.
If you want to simply remove a newline at the end of the received bytes, change the code in your while loop like so:
while ((bytes = receiveStream.Read(buff, 0, 1024)) > 0)
{
if (buff[bytes-1] == 0x0a)
bytes -= 1;
//Write the stream directly to the client
context.Response.OutputStream.Write(buff, 0, bytes);
context.Response.Write("&token="+token);
}
Several caveats:
It will only work if 0x0a (newline byte, '\n' as a character) is at the end of the bytes you received. If for some reason the message sent by the server is received in several blocks, you will first have to make sure you received everything there is to receive before checking the last byte.
Please also note that this would result in multiple &token=... lines in your current code.
Depending on the server, it might use carriage return (0x0d or '\r') as its line ending byte, or even both. Check what the server sends and adapt the code accordingly.
Related
I have to create a TCP/IP client against a existing server (which has a specific documentation), I followed same but still no response getting from server.
Initially it was the problem of Message format and SMTP Commands, which i replaced from another working command.
I have to use SSL without client certificate for login.
TcpClient client = new TcpClient("Server DNS", PORT);
Console.WriteLine("-------------------------- \nConnection is : " + client.Connected);
SslStream stream = new SslStream(client.GetStream(), false, VerifyServerCertificate, null);
stream.AuthenticateAsClient("Server DNS");
Console.Write("Authentication status :" + stream.IsAuthenticated);
// FOR NOW I AM ONLY SENDING LOGIN COMMAND
string line = "BDAT 30 LAST<EOL>{login command}<LF>useridpassword";
stream.Write(Encoding.UTF8.GetBytes(line));
stream.Flush();
string serverMessage = ReadMessage(stream);
Console.WriteLine("\nServer says: {0}", serverMessage);
stream.Close();
This sends the command but return message is always empty.
here is method i am using for ReadMessage.
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the client.
// The client signals the end of the message using the
// "<EOF>" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
sslStream.ReadTimeout = 60000;
do
{
// Read the client's test message.
bytes = sslStream.Read(buffer, 0, buffer.Length);
sslStream.Flush();
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
// Check for EOF or an empty message.
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
break;
}
} while (bytes != 0);
return messageData.ToString();
}
Below is the screenshot for same code
console error
I am also getting this error when use break points
Sorry for this long post but i think these info was necessary.
Please any help is appreciated .. Its very frustrating situation as i couldn't proceed since last 8 days bcz of it.
Thank you.
I'm trying to send large files to Asp.net server from my Xamarin Android application. I found the best way to do it would be to send the file in chunks rather than sending it whole. I'm following the tutorial here which usesHttpWebRequest to send the request to the server. In the following lines of code in the tutorial, the file is sent in chunks to the server:
/ Send the file binaries over to the server, in 1024 bytes chunk
FileStream fileStream = new FileStream(fileUrl, FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
s.Write(buffer, 0, bytesRead);
} // end while
fileStream.Close();
I know that s.Write(buffer, 0, bytesRead) writes the byte on the network socket but how does the back and forth communication work? Does the client wait for the server to respond and send the next chunk to the server or all chunks are written on the network stream and sent together?
Right now the server code I have receives the request which is the full file rather than it's chunks. My server side code looks like this:
public async Task<HttpResponseMessage> UploadFile()
{
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0)
{
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName);
postedFile.SaveAs(filePath);
// NOTE: To store in memory use postedFile.InputStream
}
return Request.CreateResponse(HttpStatusCode.Created);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
How can I make sure that the connection doesn't time out while the file is sending and is this the most efficient way of sending large file to the server? How can I resume the upload if their a blimp in the netowrk connection on the client side?
I've got a client / server application that works pretty well, but it's missing one crucial piece of behavior to make it a bit more solid.
Right now, it's far from "strong" in terms of network capabilities. I'm trying to get it there, and research has lead me to believe that I need some sort of protocol in place to ensure that no data is lost during network transmissions.
I've heard of a few methods. One that I think will work best for our situations is to use a terminator, something like an <EOF> tag. My issue is that I'm not sure of the best way to implement this.
Here's a couple code snippets that I'll be modifying to include a terminator after figuring out the best solution.
Client:
TcpClient client = new TcpClient();
client.Connect(hostname, portNo);
using (var stream = client.GetStream())
{
//send request
stream.Write(data, 0, data.Length);
stream.Flush();
//read server response
if (stream.CanRead)
{
byte[] buffer = new byte[1024];
string response = "";
int bytesRead = 0;
do
{
bytesRead = stream.Read(buffer, 0, buffer.Length);
response += Encoding.ASCII.GetString(buffer, 0, bytesRead);
} //trying to replace 'DataAvailable', it doesn't work well
while (stream.DataAvailable);
}
}
Note that I'm trying to replace the stream.DataAvailable method of checking for more data in the stream. It's been causing problems.
Server:
var listener = new TcpListener(IPAddress.Any, portNo);
listener.Start();
var client = listener.AcceptTcpClient();
using (var stream = client.GetStream())
{
var ms = new System.IO.MemoryStream();
byte[] buffer = new byte[4096];
int bytesRead = 0;
do
{
bytesRead = stream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, bytesRead);
} //also trying to replace this 'stream.DataAvailable'
while (stream.DataAvailable);
ms.Position = 0;
string requestString = Encoding.UTF8.GetString(ms.ToArray());
ms.Position = 0;
/*
process request and create 'response'
*/
byte[] responseBytes = Encoding.UTF8.GetBytes(response);
stream.Write(responseBytes, 0, responseBytes.Length);
stream.Flush();
}
So, given these two code examples, how can I modify these to both include and check for some sort of data terminator that indicates it's safe to stop reading data?
You can rely on TCP transmitting all the data before the FIN. The problem with your code is that available() is not a valid test for end of stream. It is a test for data being available now.
So you are terminating your reading loop prematurely, and thus missing data at the receiver, and getting resets at the sender.
You should just block in the Read() method until you receive the EOS indication from the API, whatever that is in C#.
You don't need your own additional EOS indicator.
We ended up using an EOS (end of stream) indicator on both ends of our project. I won't post the full code example, but here's a small snippet of how it works:
stream.Write(data, 0, data.Length);
stream.WriteByte(Convert.ToByte(ConsoleKey.Escape));
stream.Flush();
On the receiving end of this stream, the loop reads data byte-by-byte. Once it receives the ConsoleKey.Escape byte, it terminates the loop. It works!
I tried to write a text file using OutputStream.Write but, I've noticed that the last character of the file is not being sent.
Whether the file is 6KB or 242KB, the last character is skipped.
AwAIB0UfFlJTSTNABEQWGgMVAhNFBkVeKgVTSx4LCVQMBUUQRUMwBVFTGwcAEAASRRNTBipNQQMFDREYB
BUAH0VIKgVLRVccCRFFGRcbR08wREgDEQENEUkCDRNOTX5cS1ZXHgQGHFYIB0NOfgUIAwMABFQABBcdUg
YpRFcDHgZBAA0TRTEDBj1KQEZXREEdRRIKHFQGK0tARgUbFRULEkUFSF9+R1FXVxwJEUUkAAFQSTBWQQ0
xBBQHDV5MUkFIOgV2RgQYDhoWE0sxTEktQAwKVx8AB0UCDRcAQyxXS1FZSBUcBAIWUldDN1dAAxEHE1QI
E0UTTkJ+TARAFgYVVBAYARdSVSpESkdXAAAcBFg=
Note: whole text is one line in the text file.
My text file is somewhat similar to the above. So can anyone help me out?
My code:
var path = Request.QueryString["path"];
path = Server.MapPath(Url.Content("~/Files/" + path + "/somefile.txt"));
Response.Buffer = false;
Response.ContentType = "text/plain";
FileInfo file = new FileInfo(path);
int len = (int)file.Length, bytes;
Response.AppendHeader("content-length", len.ToString());
byte[] buffer = new byte[1024];
Stream outStream = Response.OutputStream;
using (Stream stream = System.IO.File.OpenRead(path))
{
while (len > 0 && (bytes = stream.Read(buffer, 0, buffer.Length)) > 0)
{
outStream.Write(buffer, 0, bytes);
len -= bytes;
}
}
Response.Flush();
Response.Close();
UPDATE 1:
Now shows the complete text from the file.
UPDATE 2 :
Updated the complete C# code.
UPDATE 3:
Thanks, my friends, for all your efforts! I somehow made it work - the problem was Response.Flush() and Response.Close(); once I removed these 2 statements it started working. I don't understand why this problem occurred as I always use Response.Flush() and Response.Close(). I never received this kind of error but this was the first time. If anyone could give me an explanation, it would be appreciated. I will mark #AlexeiLevenkov's post as the answer, as I just tested it again without the Response.Flush and Close() and it is working.
Stream.CopyTo is easier approaach (as long as you can use .Net 4.0).
using (var stream = System.IO.File.OpenRead(path))
{
stream.CopyTo(outStream);
}
I think you need to call Response.Flush() or outStream.Flush()
I'm having trouble reading a "chunked" response when using a StreamReader to read the stream returned by GetResponseStream() of a HttpWebResponse:
// response is an HttpWebResponse
StreamReader reader = new StreamReader(response.GetResponseStream());
string output = reader.ReadToEnd(); // throws exception...
When the reader.ReadToEnd() method is called I'm getting the following System.IO.IOException: Unable to read data from the transport connection: The connection was closed.
The above code works just fine when server returns a "non-chunked" response.
The only way I've been able to get it to work is to use HTTP/1.0 for the initial request (instead of HTTP/1.1, the default) but this seems like a lame work-around.
Any ideas?
#Chuck
Your solution works pretty good. It still throws the same IOExeception on the last Read(). But after inspecting the contents of the StringBuilder it looks like all the data has been received. So perhaps I just need to wrap the Read() in a try-catch and swallow the "error".
Haven't tried it this with a "chunked" response but would something like this work?
StringBuilder sb = new StringBuilder();
Byte[] buf = new byte[8192];
Stream resStream = response.GetResponseStream();
string tmpString = null;
int count = 0;
do
{
count = resStream.Read(buf, 0, buf.Length);
if(count != 0)
{
tmpString = Encoding.ASCII.GetString(buf, 0, count);
sb.Append(tmpString);
}
}while (count > 0);
I am working on a similar problem. The .net HttpWebRequest and HttpWebRequest handle cookies and redirects automatically but they do not handle chunked content on the response body automatically.
This is perhaps because chunked content may contain more than simple data (i.e.: chunk names, trailing headers).
Simply reading the stream and ignoring the EOF exception will not work as the stream contains more than the desired content. The stream will contain chunks and each chunk begins by declaring its size. If the stream is simply read from beginning to end the final data will contain the chunk meta-data (and in case where it is gziped content it will fail the CRC check when decompressing).
To solve the problem it is necessary to manually parse the stream, removing the chunk size from each chunk (as well as the CR LF delimitors), detecting the final chunk and keeping only the chunk data. There likely is a library out there somewhere that does this, I have not found it yet.
Usefull resources :
http://en.wikipedia.org/wiki/Chunked_transfer_encoding
https://www.rfc-editor.org/rfc/rfc2616#section-3.6.1
I've had the same problem (which is how I ended up here :-). Eventually tracked it down to the fact that the chunked stream wasn't valid - the final zero length chunk was missing. I came up with the following code which handles both valid and invalid chunked streams.
using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
StringBuilder sb = new StringBuilder();
try
{
while (!sr.EndOfStream)
{
sb.Append((char)sr.Read());
}
}
catch (System.IO.IOException)
{ }
string content = sb.ToString();
}
After trying a lot of snippets from StackOverflow and Google, ultimately I found this to work the best (assuming you know the data a UTF8 string, if not, you can just keep the byte array and process appropriately):
byte[] data;
var responseStream = response.GetResponseStream();
var reader = new StreamReader(responseStream, Encoding.UTF8);
data = Encoding.UTF8.GetBytes(reader.ReadToEnd());
return Encoding.Default.GetString(data.ToArray());
I found other variations work most of the time, but occasionally truncate the data. I got this snippet from:
https://social.msdn.microsoft.com/Forums/en-US/4f28d99d-9794-434b-8b78-7f9245c099c4/problems-with-httpwebrequest-and-transferencoding-chunked?forum=ncl
It is funny. During playing with the request header and removing "Accept-Encoding: gzip,deflate" the server in my usecase did answer in a plain ascii manner and no longer with chunked, encoded snippets. Maybe you should give it a try and keep "Accept-Encoding: gzip,deflate" away. The idea came while reading the upper mentioned wiki in topic about using compression.