GZipStream, how correctly read from GZipStream - c#

I have some code writen by me in C#
string host = new Uri(_url).Host;
IPHostEntry ipAddress = Dns.GetHostEntry(host);
IPEndPoint ip = new IPEndPoint(ipAddress.AddressList[0], 80);
using (Socket s = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
s.Connect(ip);
using (NetworkStream n = new NetworkStream(s))
{
byte[] write = encoding.GetBytes(HttpQuery);
n.Write(write, 0, write.Length);
ReadLine(n);
Dictionary<string, string> headers = new Dictionary<string, string>();
while (true)
{
string line = ReadLine(n);
if (line.Length == 0)
{
break;
}
int index = line.IndexOf(':');
if (!headers.ContainsKey(line.Substring(0, index)))
{
headers.Add(line.Substring(0, index), line.Substring(index + 2));
}
}
string contentEncoding;
if (headers.TryGetValue("Content-Encoding", out contentEncoding))
{
Stream responseStream = n;
if (contentEncoding.Equals("gzip"))
{
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
responseStream.Flush();
}
else if (contentEncoding.Equals("deflate"))
{
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
}
MemoryStream memStream = new MemoryStream();
byte[] respBuffer = new byte[4096];
try
{
int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
//int bytesRead = responseStream.ReadByte();
while (bytesRead > 0)
{
memStream.Write(respBuffer, 0, bytesRead);
bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
}
}
finally
{
responseStream.Close();
}
string str = encoding.GetString(memStream.ToArray());
Then I Have an exception InvalidDataException in this line int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
GZip header magic number is not correct.
string ReadLine(Stream stream)
{
List<byte> lineBuffer = new List<byte>();
try
{
while (true)
{
int b = stream.ReadByte();
if (b == -1)
return null;
if (b == 10)
break;
if (b != 13)
lineBuffer.Add((byte) b);
}
}
catch (Exception)
{
}
return encoding.GetString(lineBuffer.ToArray());
}
Any ideas?

Your ReadLine function returns as soon as it reads one line feed character when reading a blank line. Doesn't that potentially leave the stream positioned at a carriage return character instead of at the beginning of the GZip data stream?

in general, I found something on the subject, here's Sockets in C#: How to get the response stream? link, there is some information that before the string (s) to do so:
Stream responseStream = n;
int magicNumber = 0;
while (magicNumber != 10)
{
magicNumber = responseStream.ReadByte();
}
if (contentEncoding.Equals("gzip"))
{
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
}
perhaps I did not quite do it correctly?
nobugz
I have very succeful code writen with WttWebRequest and HttpWebResponse, BUT my page have codepape-1251, and HttpWebRequest convert url from 1251 encoding to UTF-8 I and nothing can do with this, maybe you have any ideas?
For example I have url as http://myurl.php?name=Мастер%20Создатель
HttpWebRequest convert this in http://myurl.php?name=%d0%9c%d0%b0%d1%81%d1%82%d0%b5%d1%80+%d0%a1%d0%be%d0%b7%d0%b4%d0%b0%d1%82%d0%b5%d0%bb%d1%8c (UTF-8)
BUT will be http://myurl.php?name=%CC%E0%F1%F2%E5%F0%20%D1%EE%E7%E4%E0%F2%E5%EB%FC(windows-1251), I don't know how fix this

Related

C# TCP Socket Stream read wrong bytes

I Read Stream with:
private Stream _Stream;
private Socket _Socket;//TCP Socket
private void ReadStream()
{
if (Guest)
{
var sizeBuffer = ReadBytes(2);//the size buffer is always 2
int size = sizeBuffer[1];
size |= (sizeBuffer[0] << 8);
var data = ReadBytes(size);
string payload = System.Text.Encoding.UTF8.GetString(data, 0, data.Length);
var tokens = SplitPayload(payload);
if (tokens[0] == "nick")
{
SetNick(tokens);
}
else
{
throw new ApplicationException("Set your nick first");
}
}
else if(!Guest)
{
var sizeBuffer = ReadBytes(2);
int size = sizeBuffer[1];
size |= (sizeBuffer[0] << 8);
var data = ReadBytes(size);
string payload = System.Text.Encoding.UTF8.GetString(data, 0, data.Length);
var tokens = SplitPayload(payload);
CheckToken(tokens);
}
if (encrypted == null)
{
encrypted = false;
byte[] sizebuffer = new byte[2];
var size = _Socket.Receive(sizebuffer);
byte[] data = new byte[size];
var datasize = _Socket.Receive(data);
if (data[0] == 0x01)
{
encrypted = true;
_Stream = new NetworkStream(_Socket, true);
var sslStream = new SslStream(_Stream, false);
serverCertificate = new X509Certificate2(Path, "");
sslStream.AuthenticateAsServer(serverCertificate);
_Stream = sslStream;
}
else
{
encrypted = false;
_Stream = new NetworkStream(_Socket, true);
}
}
}
I write to the stream with:
private void SendServerMsg(string[] arguments)
{
var msg = string.Join("\0", arguments);
byte[] data = Encoding.UTF8.GetBytes(msg);
byte[] sizeinfo = new byte[2];
sizeinfo[1] = (byte)data.Length;
sizeinfo[0] = (byte)(data.Length >> 8);
_Stream.Write(sizeinfo, 0, sizeinfo.Length);
_Stream.Write(data, 0, data.Length);
}
my Problem is now:
1. When I make a Breakpoint at the line
_Stream.Write(sizeinfo, 0, sizeinfo.Length);
and step through manualy all work. The TCP _Socket gets the correct bytes,
but with no breakpoint the server stucks in the line
var data = ReadBytes(size);
and the size is more than 5000 but I send not more than 15 bytes (for example: "nick\0test")
hear is the readBytes method
private byte[] ReadBytes(int count)
{
byte[] buffer = new byte[count];
for (var i = 0; i < count; i++)
{
var oneByte = _Stream.ReadByte();
if (oneByte == -1)
{
break;
}
buffer[i] = (byte)oneByte;
}
return buffer;
}

How to stream an mp3 file using a temporary file?

I am working an Mp3 streamer. To stream mp3 file from url, I want to use a temporary file. But trying to read and write the same file throws IOException for File.ReadAllBytes because the file is in use. How can I get throught this problem?
long pos = 0;
string path = pathtothetempfile;
MemoryStream ms = new MemoryStream();
FileStream fs = new FileStream(path, FileMode.Create,
FileAccess.ReadWrite, FileShare.ReadWrite);
do
{
bytesRead = responseStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, bytesRead);
fs.Flush();
byte[] tempBuffer = File.ReadAllBytes(path);
pos = ms.Position;
ms = new MemoryStream(tempBuffer);
ms.Position = pos;
frame = Mp3Frame.LoadFromStream(ms);
//....codes....
}
while(bytesRead > 0)
I have found an answer by myself by searching so much. This answer contains NAudio to control the Mp3 and it is RAM friendly by reading stream partially. I am sharing it for other people who has the same problem.
WaveOut waveOut;
AcmMp3FrameDecompressor decompressor;
BufferedWaveProvider provider;
bool firstPlay = true;
public void Play()
{
Task.Run(() =>
{
#region WebRequest creator
HttpWebResponse response = null;
if (avgbytes < 0)
{
HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
req.AllowAutoRedirect = true;
req.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0";
response = req.GetResponse() as HttpWebResponse;
contentLength = response.ContentLength;
}
else
response = Helper.CreateAudioWebRequest(url, currentTime, avgbytes)
.GetResponse() as HttpWebResponse;
Stream responseStream = response.GetResponseStream();
#endregion
#region Local Variables
byte[] buffer = new byte[17 * 1024];
byte[] bigBuffer = new byte[response.ContentLength];
int bytesRead = 0;
long pos = 0;
long postotal = 0;
string path = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".mp3";
#endregion
Mp3Frame frame;
FileStream fs = new FileStream(path,
FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
do
{
bytesRead = responseStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, bytesRead);
fs.Flush();
using (MemoryStream ms = new MemoryStream(ReadPartial(fs, postotal, 1024 * 10)))
{
ms.Position = 0;
frame = Mp3Frame.LoadFromStream(ms);
if (frame == null)
{
continue;
}
pos = ms.Position;
postotal += pos;
}
#region First Play
if (firstPlay)
{
avgbytes = new Mp3WaveFormat(frame.SampleRate, frame.ChannelMode == ChannelMode.Mono ? 1 : 2,
frame.FrameLength, frame.BitRate).AverageBytesPerSecond;
duration = (int)(response.ContentLength * 1d / avgbytes);
firstPlay = false;
}
#endregion
#region Decompress Frame
if (decompressor == null)
{
decompressor = CreateFrameDecompressor(frame) as AcmMp3FrameDecompressor;
provider = new BufferedWaveProvider(decompressor.OutputFormat);
provider.BufferDuration = TimeSpan.FromSeconds(20);
}
int decompressed = decompressor.DecompressFrame(frame, buffer, 0);
#endregion
#region BufferedWaveProvider Area
if (IsBufferNearlyFull(provider))
{
Thread.Sleep(500);
}
provider.AddSamples(buffer, 0, decompressed);
#endregion
if (provider.BufferedDuration.TotalSeconds >= 2 && waveOut == null)
{
waveOut = new WaveOut();
waveOut.Init(provider);
waveOut.Play();
}
}
while (postotal != contentLength || bytesRead > 0 || waveOut==null ||
(waveOut != null && waveOut.PlaybackState == PlaybackState.Playing));
});
}
public static byte[] ReadStreamPartially(System.IO.Stream stream, long offset, long count)
{
long originalPosition = 0;
if (stream.CanSeek)
{
originalPosition = stream.Position;
stream.Position = offset;
}
try
{
byte[] readBuffer = new byte[4096];
byte[] total = new byte[count];
int totalBytesRead = 0;
int byteRead;
while ((byteRead = stream.ReadByte()) != -1)
{
Buffer.SetByte(total, totalBytesRead, (byte)byteRead);
totalBytesRead++;
if (totalBytesRead == count)
{
stream.Position = originalPosition;
break;
}
}
if (totalBytesRead < count)
{
byte[] temp = new byte[totalBytesRead];
Buffer.BlockCopy(total, 0, temp, 0, totalBytesRead);
stream.Position = originalPosition;
return temp;
}
return total;
}
finally
{
if (stream.CanSeek)
{
stream.Position = originalPosition;
}
}
}
private bool IsBufferNearlyFull(BufferedWaveProvider bufferedWaveProvider)
{
return bufferedWaveProvider != null &&
bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes
< bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4;
}
private static IMp3FrameDecompressor CreateFrameDecompressor(Mp3Frame frame)
{
WaveFormat waveFormat = new Mp3WaveFormat(frame.SampleRate, frame.ChannelMode == ChannelMode.Mono ? 1 : 2,
frame.FrameLength, frame.BitRate);
return new AcmMp3FrameDecompressor(waveFormat);
}

A simple web server to consume a POST request - Server hangs after one or two requests

I am building a small windows application to consume a POST request. The code below works fine for GET requests and for the first POST request. Basically when I read the POST DATA it works fine the first time (or the first few times). After a while (a few seconds - it hangs. Any incoming request hangs. Any ideas? Assume the content length is correct.
while (true)
{
System.Console.WriteLine("The server is running at port 8001...");
System.Console.WriteLine("Waiting for a connection.....");
TcpClient client = _listener.AcceptTcpClient();
int incomingDataLength = client.ReceiveBufferSize;
Stream ist = client.GetStream();
BufferedStream bst = new BufferedStream(ist);
int k = 0;
String line = ReadLine(bst);
System.Console.WriteLine(line);
while ((line = ReadLine(bst)) != null)
{
if (line == "") break;
System.Console.WriteLine(line);
}
MemoryStream ms = new MemoryStream();
int contentLen = 3429;
//if (this.HttpHeaders.ContainsKey("Content-Length"))
{
//content_len = Convert.ToInt32(this.HttpHeaders["Content-Length"]);
byte[] buf = new byte[4096];
int to_read = content_len;
while (to_read > 0)
{
int numread = bst.Read(buf, 0, Math.Min(buf.Length, to_read));
if (numread == 0)
{
if (to_read == 0) break;
else throw new Exception("client disconnected during post");
}
to_read -= numread;
ms.Write(buf, 0, numread);
}
ms.Seek(0, SeekOrigin.Begin);
}
using (StreamReader sr = new StreamReader(ms))
{
System.Console.WriteLine(sr.ReadToEnd());
}
bst.Close();
client.Close();
And the ReadLine is
private String ReadLine(Stream stream)
{
int k;
StringBuilder lineBuilder = new StringBuilder();
while (true)
{
k = stream.ReadByte();
if (k < 0) continue;
char c = Convert.ToChar(k);
if (c == '\n') break;
if (c == '\r') continue;
lineBuilder.Append(c);
}
return lineBuilder.ToString();
}
As Yannis suggested, you may not be disposing your objects, especially your streams. Using statements, like you did with the StreamReader, will automatically do this for you. For example:
while (true)
{
System.Console.WriteLine("The server is running at port 8001...");
System.Console.WriteLine("Waiting for a connection.....");
using (TcpClient client = _listener.AcceptTcpClient())
{
int incomingDataLength = client.ReceiveBufferSize;
using (Stream ist = client.GetStream())
{
//Stream ist = client.GetStream();
using (BufferedStream bst = new BufferedStream(ist))
{
//BufferedStream bst = new BufferedStream(ist);
int k = 0;
String line = ReadLine(bst);
System.Console.WriteLine(line);
while ((line = ReadLine(bst)) != null)
{
if (line == "") break;
System.Console.WriteLine(line);
}
using (MemoryStream ms = new MemoryStream())
{
//MemoryStream ms = new MemoryStream();
int contentLen = 3429;
if (this.HttpHeaders.ContainsKey("Content-Length"))
{
//content_len = Convert.ToInt32(this.HttpHeaders["Content-Length"]);
byte[] buf = new byte[4096];
int to_read = content_len;
while (to_read > 0)
{
int numread = bst.Read(buf, 0, Math.Min(buf.Length, to_read));
if (numread == 0)
{
if (to_read == 0) break;
else throw new Exception("client disconnected during post");
}
to_read -= numread;
ms.Write(buf, 0, numread);
}
ms.Seek(0, SeekOrigin.Begin);
}
using (StreamReader sr = new StreamReader(ms))
{
System.Console.WriteLine(sr.ReadToEnd());
}
//bst.Close();
client.Close();
} //end memorystream
} //end bufferedsteam
} //end stream
} //end tcpClient
} //end while

Sockets in Visual C#. Need Help!

I'm from the Urkraine, and have bad english, but anyway not sure if there is an answer on my question.
I took example from [here][1] but i have exception that GZip magical number is not valid, why ?
public long WriteUrl()
{
long num1 = 0;
bool saveItAtCache = false;
bool existsAtCache = false;
byte[] cachedFile = null;
string ext = Path.GetExtension(_url).ToLower();
if (!_url.Contains(".php") && ".gif.jpg.swf.js.css.png.html".IndexOf(ext) != -1 && ext != "")
{
saveItAtCache = true;
cachedFile = cache.GetFile(_url);
existsAtCache = (cachedFile != null);
}
if (existsAtCache)
{
writeSuccess(cachedFile.Length, null);
socket.Send(cachedFile);
}
string host = new Uri(_url).Host;
IPHostEntry ipAddress = Dns.GetHostEntry(host);
IPEndPoint ip = new IPEndPoint(ipAddress.AddressList[0], 80);
using (Socket s = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
s.Connect(ip);
using (NetworkStream n = new NetworkStream(s))
{
if (HttpRequestType == "GET")
{
SendRequest(n, new[] { socketQuery});
}
Dictionary<string, string> headers = new Dictionary<string, string>();
while (true)
{
string line = ReadLine(n);
if (line.Length == 0)
{
break;
}
int index = line.IndexOf(':');
if (!headers.ContainsKey(line.Substring(0, index)))
{
headers.Add(line.Substring(0, index), line.Substring(index + 2));
}
}
string contentEncoding;
if (headers.TryGetValue("Content-Encoding", out contentEncoding))
{
Stream responseStream = n;
if (contentEncoding.Equals("gzip"))
{
responseStream = new GZipStream(responseStream, CompressionMode.Decompress, true);
}
else if (contentEncoding.Equals("deflate"))
{
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
}
var memStream = new MemoryStream();
var respBuffer = new byte[4096];
try
{
int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
//int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
while (bytesRead > 0)
{
memStream.Write(respBuffer, 0, bytesRead);
bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
}
}
finally
{
responseStream.Close();
}
string str = encoding.GetString(memStream.ToArray());
ManageCookies(headers["Set-Cookie"], _headers["Host"]);
cachedFile = encoding.GetBytes(str);
if (saveItAtCache)
{
cache.Store(_url, cachedFile);
}
writeSuccess(cachedFile.Length, headers["Set-Cookie"]);
socket.Send(cachedFile);
num1 = str.Length;
}
else
{
while (true)
{
string line = ReadLine(n);
if (line == null)
{
break;
}
num1 = line.Length;
}
}
}
}
return num1;
}
In these lines
string str = encoding.GetString(memStream.ToArray());
ManageCookies(headers["Set-Cookie"], _headers["Host"]);
cachedFile = encoding.GetBytes(str);
You're converting the byte array to a string and then back to a byte array. Since the original data is a gzip or jpg or whatever and not really a string, this conversion is probably screwing it up. I don't see you using str at all, so just take it out (use cachedFile.Length when you need the length instead of str.Length).

Sockets in C#: How to get the response stream?

I'm trying to replace this:
void ProcessRequest(object listenerContext)
{
var context = (HttpListenerContext)listenerContext;
Uri URL = new Uri(context.Request.RawUrl);
HttpWebRequest.DefaultWebProxy = null;
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(URL);
httpWebRequest.Method = context.Request.HttpMethod;
httpWebRequest.Headers.Clear();
if (context.Request.UserAgent != null) httpWebRequest.UserAgent = context.Request.UserAgent;
foreach (string headerKey in context.Request.Headers.AllKeys)
{
try { httpWebRequest.Headers.Set(headerKey, context.Request.Headers[headerKey]); }
catch (Exception) { }
}
using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
{
Stream responseStream = httpWebResponse.GetResponseStream();
if (httpWebResponse.ContentEncoding.ToLower().Contains("gzip"))
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
else if (httpWebResponse.ContentEncoding.ToLower().Contains("deflate"))
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
MemoryStream memStream = new MemoryStream();
byte[] respBuffer = new byte[4096];
try
{
int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
while (bytesRead > 0)
{
memStream.Write(respBuffer, 0, bytesRead);
bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
}
}
finally
{
responseStream.Close();
}
byte[] msg = memStream.ToArray();
context.Response.ContentLength64 = msg.Length;
using (Stream strOut = context.Response.OutputStream)
{
strOut.Write(msg, 0, msg.Length);
}
}
catch (Exception ex)
{
// Some error handling
}
}
with sockets. This is what I have so far:
void ProcessRequest(object listenerContext)
{
HttpListenerContext context = (HttpListenerContext)listenerContext;
Uri URL = new Uri(context.Request.RawUrl);
string getString = string.Format("GET {0} HTTP/1.1\r\nHost: {1}\r\nAccept-Encoding: gzip\r\n\r\n",
context.Request.Url.PathAndQuery,
context.Request.UserHostName);
Socket socket = null;
string[] hostAndPort;
if (context.Request.UserHostName.Contains(":"))
{
hostAndPort = context.Request.UserHostName.Split(':');
}
else
{
hostAndPort = new string[] { context.Request.UserHostName, "80" };
}
IPHostEntry ipAddress = Dns.GetHostEntry(hostAndPort[0]);
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(ipAddress.AddressList[0].ToString()), int.Parse(hostAndPort[1]));
socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(ip);
BEGIN NEW CODE
Encoding ASCII = Encoding.ASCII;
Byte[] byteGetString = ASCII.GetBytes(getString);
Byte[] receiveByte = new Byte[256];
string response = string.Empty;
socket.Send(byteGetString, byteGetString.Length, 0);
Int32 bytes = socket.Receive(receiveByte, receiveByte.Length, 0);
response += ASCII.GetString(receiveByte, 0, bytes);
while (bytes > 0)
{
bytes = socket.Receive(receiveByte, receiveByte.Length, 0);
strPage = strPage + ASCII.GetString(receiveByte, 0, bytes);
}
socket.Close();
string separator = "\r\n\r\n";
string header = strPage.Substring(0,strPage.IndexOf(separator));
string content = strPage.Remove(0, strPage.IndexOf(separator) + 4);
byte[] byteResponse = ASCII.GetBytes(content);
context.Response.ContentLength64 = byteResponse .Length;
context.Response.OutputStream.Write(byteResponse , 0, byteResponse .Length);
context.Response.OutputStream.Close();
END NEW CODE
After connecting to the socket I don't know how to get the Stream response to decompress, and send back to context.Response.OutputStream
Any help will be appreciated.
Thanks.
Cheers.
EDIT 2:
With this edit now seems to be working fine (same as HttpWebRequest at least). Do you find any error here?
EDIT 3:
False alarm... Still can't get this working
EDIT 4:
I needed to add the following lines to Scott's code ... because not always the first to bytes of reponseStream are the gzip magic number.
The sequence seems to be: 0x0a (10), 0x1f (31), 0x8b (139). The last two are the gzip magic number. The first number was always before in my tests.
if (contentEncoding.Equals("gzip"))
{
int magicNumber = 0;
while (magicNumber != 10)
magicNumber = responseStream.ReadByte();
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
}
Here's some code that works for me.
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO.Compression;
namespace HttpUsingSockets {
public class Program {
private static readonly Encoding DefaultEncoding = Encoding.ASCII;
private static readonly byte[] LineTerminator = new byte[] { 13, 10 };
public static void Main(string[] args) {
var host = "stackoverflow.com";
var url = "/questions/523930/sockets-in-c-how-to-get-the-response-stream";
IPHostEntry ipAddress = Dns.GetHostEntry(host);
var ip = new IPEndPoint(ipAddress.AddressList[0], 80);
using (var socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) {
socket.Connect(ip);
using (var n = new NetworkStream(socket)) {
SendRequest(n, new[] {"GET " + url + " HTTP/1.1", "Host: " + host, "Connection: Close", "Accept-Encoding: gzip"});
var headers = new Dictionary<string, string>();
while (true) {
var line = ReadLine(n);
if (line.Length == 0) {
break;
}
int index = line.IndexOf(':');
headers.Add(line.Substring(0, index), line.Substring(index + 2));
}
string contentEncoding;
if (headers.TryGetValue("Content-Encoding", out contentEncoding)) {
Stream responseStream = n;
if (contentEncoding.Equals("gzip")) {
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
}
else if (contentEncoding.Equals("deflate")) {
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
}
var memStream = new MemoryStream();
var respBuffer = new byte[4096];
try {
int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
while (bytesRead > 0) {
memStream.Write(respBuffer, 0, bytesRead);
bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
}
}
finally {
responseStream.Close();
}
var body = DefaultEncoding.GetString(memStream.ToArray());
Console.WriteLine(body);
}
else {
while (true) {
var line = ReadLine(n);
if (line == null) {
break;
}
Console.WriteLine(line);
}
}
}
}
}
static void SendRequest(Stream stream, IEnumerable<string> request) {
foreach (var r in request) {
var data = DefaultEncoding.GetBytes(r);
stream.Write(data, 0, data.Length);
stream.Write(LineTerminator, 0, 2);
}
stream.Write(LineTerminator, 0, 2);
// Eat response
var response = ReadLine(stream);
}
static string ReadLine(Stream stream) {
var lineBuffer = new List<byte>();
while (true) {
int b = stream.ReadByte();
if (b == -1) {
return null;
}
if (b == 10) {
break;
}
if (b != 13) {
lineBuffer.Add((byte)b);
}
}
return DefaultEncoding.GetString(lineBuffer.ToArray());
}
}
}
You could substitute this for the Socket/NetworkStream and save a bit of work.
using (var client = new TcpClient(host, 80)) {
using (var n = client.GetStream()) {
}
}
Socket, by definition, is the low level to access the network. You can even use datagram protocols with a socket. In that case a stream does not make sense at all.
While I'm not sure why are you doing what HttpWebRequest easily accomplishes, to read/write data to a socket, you use the Send/Receive methods. If you want to have a stream like access to a TCP socket, you should use the TcpClient/TcpListener classes which wrap a socket and provide a network stream for it.
There's also the NetworkStream class that takes a Socket as a parameter. ;)

Categories