Use Socket for received File in windows phone - c#

I read the msdn tutorial for using socket with Windows phone. (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket(v=VS.96).aspx) I arrived to connect me to the server.
This, return me an response 200 ( OK response ) =>
HTTP/1.1 200 OK
Date: Mon, 16 Apr 2012 12:45:46 GMT
Server: Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny13 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8g
Last-Modified: Tue, 08 Aug 2006 14:12:09 GMT
ETag: "129a2e5-100000-41a822e23a040"
Accept-Ranges: byte
But I don't know what to do next...
I connect me to the server, I sent this a "GET Message" for download a file
"GET /dwn/file.txt HTTP/1.1\r\nHost:myHost.com\r\n\r\n"
and After the response ? I have to do what?
If you know a tutorial, sample, or just explication, I would thank you greatly!
this my function =>
private void ProcessReceive(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
// show the response server value.
Debug.WriteLine(response.ToString());
// Data has now been sent and received from the server.
// Disconnect from the server
socket = e.UserToken as Socket;
socket.Shutdown(SocketShutdown.Send);
socket.Close();
clientDone.Set();
}
else
{
// show error in the debugger.
response = e.SocketError.ToString();
Debug.WriteLine(response);
}
}

Why don't you use WebClient or something like that ?
If it's just for experiencing, you should know that this is not a trivial task. Here are some hints:
You will probably not receive the whole HTTP response header + body in one "Receive" call. Remember, a TCP socket is a stream.
HTTP Headers are encoded in 7 bit ASCII, not UTF8.
HTTP Entity (well, body) encoding depends on headers, and decoding it can be tricky.
Have fun !
Edit
Clarifications (point #1):
// Data has now been sent and received from the server.
// Disconnect from the server
socket = e.UserToken as Socket;
socket.Shutdown(SocketShutdown.Send);
socket.Close();
Why do you shutdown and close the socket now? The response body follows the header in the stream. As I said, there is probably more bytes waiting to be received from the server. Continue to call "receive" until either:
There is no more bytes to read (socket is closed by the server)
You are sure you've read the whole response body (see "Content-Length" or "Transfer-Encoding" headers)

Related

How to read a response with Content-Length 0?

I need to read a body of a response where a Content-Length is explicitly specified as zero. But the stream.Read does not read anything and returns 0. When the Content-Length header is not present, it reads all the bytes successfully.
When I open the web page in the browser it is empty, but I can see the contents in Fiddler.
Is there any way to get the Stream returned from GetResponseStream to read the bytes when the Content-Length is 0?
Sample response:
HTTP/1.1 200 OK
Cache-Control: public, must-revalidate
ETag: "c7f40cb26b1e95c2245f1584371465582f996a8a88b34a2cc99bbe922b1a2857"
Vary: Accept-Encoding
X-Request-Id: 4b799b6d-cd68-47f7-a392-4fd0a327f5de
X-Runtime: 0.001646
Content-Length: 0
- some content -
Simplified version of the code:
using(var stream = httpRes.GetResponseStream())
{
while (true)
{
var bytesRead = stream.Read(
responseBuffer,
0,
responseBuffer.Length);
// other stuff
}
}
When an HTTP/1.1 has Content-Length: 0, then, by definition, there is no payload to read. If bytes follow, they by definition are the response to the subsequent request.
Now, obviously, this is not the case here. So, just to be absolutely clear: you're asking for a workaround to deal with a broken server. It would be much cleaner to fix the server instead.

Why does web browser makes two requests to download a mp3 file?

I am creating a very simple web server where its only purpose is to return an mp3 file.
// create server
TcpListener server = new TcpListener(8585);
server.Start();
while (true)
{
// accept a new client
using (var client = server.AcceptTcpClient())
{
byte[] buffer = new byte[1024 * 2];
var i = client.Client.Receive(buffer);
// get request client sent us
var request = System.Text.Encoding.UTF8.GetString(buffer, 0, i).ToLower();
// if the browser is requesting an icon return
if (request.Contains("/favicon.ico"))
{
continue;
}
// with fiddler when I downloaded great.mp3 I saved the response as a binary file to make sure I am returning the right output
client.Client.Send(System.IO.File.ReadAllBytes("cheat.bin"));
}
}
cheat.bin can be downloaded from here
it basically consists of
HTTP/1.1 200 OK
Server: Apache/2.2.3 (CentOS)
X-HOST: sipl-web-233.oddcast.com
X-TTSCache: HIT
X-TTSCacheInsert: NO
Content-Type: audio/mpeg
Access-Control-Allow-Origin: *
Vary: Accept-Encoding
Date: Thu, 01 May 2014 00:02:15 GMT
Content-Length: 5471
Connection: keep-alive
ID3���� .... rest of mp3 file!
So my question is why is it that when I go to http://localhost:8585/getSong on my web browser the song is downloaded twice? In other words if I place a breakpoint in my code I hit it twice. Also I will not be able to play the audio in the browser until I return the song a second time.
I am asking this question primarily to learn. I dont understand what is wrong.
Browsers often make a HTTP head call before a HTTP get don't they? Could that be why?
https://ochronus.com/http-head-request-good-uses/
Anyway I would use something like Fiddler to see exactly what HTTP requests the browser is making.

how to send POST without waiting response C#

how to send POST without waiting response in C#?
How can I do it?
Help please!
Use one of the asynchronous methods in the WebClient class, for example UploadStringAsync.
The corresponding event (UploadStringCompleted for the example) will be triggered when the post is completed (or fails), but you don't have to hook up any handler for the event. You might want to do that, however, to check if there was any error.
An HTTP session is just a standard TCP session, and a POST is just a properly formatted piece of data that meets the HTTP specification. You can open a TCP connection to the web server and send a POST request and then close the TCP connection. You can check the HTTP specification (RFC 2616) to learn how to properly format a POST. You can find it at: http://www.w3.org/Protocols/rfc2616/rfc2616.html
A very basic POST would be sending the following over a TCP connection:
POST / HTTP/1.1
Host: www.thehost.com
Content-Length: 3
Content-Type: application/x-www-form-urlencoded
Hi!
Substituting the content, and the corresponding length with whatever you want to send, changing the / to the correct path and putting the hostname or IP of the host at Host:... and connecting the TCP session to that host of course.
A very very basic example:
using System.Net;
using System.Net.Sockets;
static void Main(string[] args)
{
string Hostname = "www.website.com";
TcpClient Client = new TcpClient(Hostname, 80);
Client.Client.Send(new ASCIIEncoding().GetBytes("POST / HTTP/1.1\nHost: "+Hostname+"\nConnection: close\n\n"));
Client.Close();
}
Changing www.website.com to the correct hostname (and the port if required).
UploadValuesAsync looks like a more complete solution, using something like this:
using (var client = new WebClient())
{
var values = new NameValueCollection();
// add values...
client.UploadValuesAsync(new System.Uri(rawUrl), "POST", values);
}
However note that I haven't tested this code as I was trying to solve a slightly different problem.
var wc = new WebClient();
wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
wc.UploadStringAsync(uri, data);
wc.UploadStringCompleted += (sender, e) =>
{
// completed
};

jQuery POST to a .NET HttpListener and back again

I have a chunk of javascript code that uses jQuery.post to send some data to a .NET app that's using an HttpListener.
Here's the js:
$.post("http://localhost:8080/catch", { name: "John", time: "2pm" },
function(data) {
alert(data);
});
and the C#:
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
StreamReader reader = new StreamReader(request.InputStream);
string s2 = reader.ReadToEnd();
Console.WriteLine("Data received:" + s2);
// Obtain a response object.
HttpListenerResponse response = context.Response;
// Construct a response.
string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// Get a response stream and write the response to it.
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
// You must close the output stream.
output.Close();
The post request goes out ok, and the .NET app reads in the data ok, but the JS code doesn't seem to get the response. The callback function to the jQuery.post fires, but data is always undefined.For brevity I have omitted some C# above where I set the prefixes to the listener.
Any ideas why I'm not getting my data back client-side?
EDIT: I should add that when I run the JS with HttpFox running I get Http code 200, 'NS_ERROR_DOM_BAD_URI', which I thought had something to do with the "http://localhost:8080/catch" I was targeting, but when I hit that resource in firefox, i get the HTML response just fine and it registers as a GET, 200.
EDIT: I simplified the response to just 'meow', and this is what fiddler is giving me for the full response:
HTTP/1.1 200 OK
Content-Length: 4
Content-Type: text/html
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 15 Apr 2011 12:58:49 GMT
meow
Don't forget about the same origin policy restriction. Unless your javascript is hosted on http://localhost:8080 you won't to be able to send AJAX requests to this URL. A different port number is not allowed either. You will need to host your javascript file on an HTML page served from http://localhost:8080 if you want this to work. Or have your server send JSONP but this works only with GET requests.
Remark: make sure you properly dispose disposable resource on your server by wrapping them in using statements or your server might start leaking network connection handles.
Don't forget to release the resources by closing the response.
Calling Close on the response will force the response to be sent through the underlying socket and will then Dispose all of its disposable objects.
In your example, the Close method is only called on the Output stream. This will send the response through the socket, but will not dispose any resources related to the response, which includes the output stream you referenced.
// Complete async GetContext and reference required objects
HttpListenerContext Context = Listener.EndGetContext(Result);
HttpListenerRequest Request = Context.Request;
HttpListenerResponse Response = Context.Response;
// Process the incoming request here
// Complete the request and release it's resources by call the Close method
Response.Close();
I do not see setting of content-type. Set the content-type to text/html.
response.ContentType = "text/html";
You can simplify the writing code a lot. Just use this:
// Construct a response.
string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
context.Response.Write(responseString);
No need for the OutputStream or most of that other code. If you do have a reason to use it, note that you actually should not close the OutputStream. When you use Resopnse.OutputStream you're retrieving a reference to it but you're not taking ownership. It's still owned by the Response object and will be closed properly when the Response is disposed at the end of the request.

How to parse a raw HTTP response as HttpListenerResponse?

If I have a raw HTTP response as a string:
HTTP/1.1 200 OK
Date: Tue, 11 May 2010 07:28:30 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
Server: gws
X-XSS-Protection: 1; mode=block
Connection: close
<!doctype html><html>...</html>
Is there an easy way I can parse it into an HttpListenerResponse object? Or at least some kind .NET object so I don't have to work with raw responses.
What I'm doing currently is extracting the header key/value pairs and setting them on the HttpListenerResponse. But some headers can't be set, and then I have to cut out the body of the response and write it to the OutputStream. But the body could be gzipped, or it could be an image, which I can't get to work yet. And some responses contain random characters everywhere, which looks like an encoding problem. It's a lot of trouble.
I'm getting a raw response because I'm using SOCKS to send an HTTP request. The program I'm working on is basically an HTTP proxy that can route requests through a SOCKS proxy, like Privoxy does.
Looks like there's no easy way to convert them. These articles helped:
How to implement custom proxy server?
http://www.jeffcrossman.com/2009/08/27/using-httplistener-to-build-a-proxy
I ended up doing something very similar.
Maybe you want to take a look at the ResponseHeaders property of the Webclient:
WebClient wc = new WebClient();
wc.DownloadStringAsync(new Uri("http://www.foo.com"));
WebHeaderCollection myWebHeaderCollection = myWebClient.ResponseHeaders;
for (int i=0; i < myWebHeaderCollection.Count; i++)
Console.WriteLine ("\t" + myWebHeaderCollection.GetKey(i) +
" = " + myWebHeaderCollection.Get(i));
Please tell me if that isnt what you were searching for.

Categories