• Welcome to Valhalla Legends Archive.
 

Help with Network Streams as well as Writers/Readers

Started by BaDDBLooD, January 31, 2006, 03:23 PM

Previous topic - Next topic

BaDDBLooD

I am trying to connect to a SOCKS4/5 Proxy Server.  I want to fully understand the process in how this works.  I will be adding Asynchronous sockets, so i figure having a base knowledge about sockets would be invaluable.



public static void Main()
{
Proxy p = new Proxy();
p.Server = "211.143.183.66";
p.Port = 1080;
p.Type = 4;

try
{
Socket mySocket;
if (mySocket = Connect(p.Server, 1080) != null)
{
NetworkStream myNetworkStream;
if (NetworkStreamOwnsSocket == true)
{
myNetworkStream = new NetworkStream(mySocket, true);
}
else if(NetworkStreamOwnsSocket == false)
{
myNetworkStream = new NetworkStream(mySocket, false);
}

if (myNetworkStream.CanWrite == true)
{
StreamWriter sw = new StreamWriter(myNetworkStream);
byte[] outbuf;
if (p.Type == 4)
{
}
else if (p.Type == 5)
{
}
}
else if (myNetworkStream.CanWrite == false)
{
Console.WriteLine("Network Stream is Not Writeable!");
}
}
}

catch (Exception e)
{
Console.WriteLine(e.ToString());
}

Console.ReadLine();
}



I am not really sure on how to phrase my questions so bare with me

You can send/receive information with just the raw socket.  From what i hear, especially on this forum, a network stream is better.  Why? What are the Advantages?

The Stream Writer and Reader Classes are also used with the NetworkStream Class, Why? What are the Advantages?

I Understand the Logic behind using these different things in succession, i just want to know WHY people use them when the classes before them can do the same thing.

Examples:

Socket can Read/Write, but people use Network Stream.
Network Stream can Read/Write, but people use Stream Reader/Writer.

How does the BitConverter Class work in Conjunction with NetworkStream and Stream Writer/Reader to send/Receive information?

Links, Code Snippets, Explanations are all VERY MUCH Appreciated

I don't really get what NetWorkStreamOwnsSocket does or why you have to specify True/False, i found the snippet on MSDN

Thank You Guys So Much  :'(

- Joel
There are only two kinds of people who are really fascinating: people who know absolutely everything, and people who know absolutely nothing.

MyndFyre

NetworkStream is nice to use because everything in .NET I/O revolves around Streams.

Want to serialize an object?  BinaryFormatter serializes objects to/from Streams.  As you mentioned, people use StreamReader/StreamWriter.  What about easily accessing binary data a chunk at a time?  Use BinaryReader/Writer.  Want to calculate a hash?  Classes in the System.Security.Cryptography namespace can calculate hashes on a Stream.

What's easier for you to code:

int curPos = 0; totLen = 20;
while (curPos < 20) {
  int nReceived = socket.Receive(buffer, curPos, totLen, SocketFlags.None);
  curPos += nReceived;
  totLen -= nReceived;
}
int dw1 = BitConverter.ToInt32(buffer, 0);
int dw2 = BitConverter.ToInt32(buffer, 4);
int dw3 = BitConverter.ToInt32(buffer, 8);
int dw4 = BitConverter.ToInt32(buffer, 12);
int dw5 = BitConverter.ToInt32(buffer, 16);

or...

int dw1 = binaryReader.ReadInt32();
int dw2 = binaryReader.ReadInt32();
int dw3 = binaryReader.ReadInt32();
int dw4 = binaryReader.ReadInt32();
int dw5 = binaryReader.ReadInt32();

?

As long as the BinaryReader owns a NetworkStream (which owns a Socket), that code is functionally identical.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

BaDDBLooD

#2
Do i use Binary Reader/Writer or Stream Reader/Writer to write/read information over the socket?

Also, how do i implement Stream Reader/Writer for sending information over TCP/IP, on MSDN it only has examples for working with text files.

I don't mind writing the code but i don't know where to begin, nor where to go once i have.

EDIT: What does serializing an object mean?  I'm not familiar with that term, and i don't really 'get' what BinaryFormatter does.
There are only two kinds of people who are really fascinating: people who know absolutely everything, and people who know absolutely nothing.

MyndFyre

Quote from: BaDDBLooD on January 31, 2006, 04:05 PM
Do i use Binary Reader/Writer or Stream Reader/Writer to write/read information over the socket?

Also, how do i implement Stream Reader/Writer for sending information over TCP/IP, on MSDN it only has examples for working with text files.

I don't mind writing the code but i don't know where to begin, nor where to go once i have.
Anything that ends in "Reader" or "Writer" in .NET is going to (or should) work on a Stream object.  The example they give with loading a text file is suboptimal because they don't show you the Stream-based constructor.

The BinaryReader example shows how to read a binary file though.  It's basically this:

FileStream fs = File.Open("c:\\binaryfile.dat", FileMode.Open);
BinaryReader br = new BinaryReader(fs);

You could do the same thing with a NetworkStream, or any other object that derives from Stream:

NetworkStream ns = new NetworkStream(mySocket);
BinaryReader br = new BinaryReader(ns);


Quote from: BaDDBLooD on January 31, 2006, 04:05 PM
EDIT: What does serializing an object mean?  I'm not familiar with that term, and i don't really 'get' what BinaryFormatter does.
Let's say you have this class:

class A { int val1; float val2; }
// you make an A
A a = new A();
a.val1 = 5;
a.val2 = 994.23884;

Let's say for whatever reason you want to be able to use that copy of A again.  You can serialize it to disk or over the network:

FileStream fs = File.Create("c:\\my A.dat");
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, a);
fs.Flush();
fs.Close();

You can deserialize that file back into a new A variable the next time you run your program.  Very handy.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

BaDDBLooD

#4
Quote from: BaDDBLooD on January 31, 2006, 04:05 PM
EDIT: What does serializing an object mean?  I'm not familiar with that term, and i don't really 'get' what BinaryFormatter does.
Let's say you have this class:

class A { int val1; float val2; }
// you make an A
A a = new A();
a.val1 = 5;
a.val2 = 994.23884;

Let's say for whatever reason you want to be able to use that copy of A again.  You can serialize it to disk or over the network:

FileStream fs = File.Create("c:\\my A.dat");
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, a);
fs.Flush();
fs.Close();

You can deserialize that file back into a new A variable the next time you run your program.  Very handy.
Quote

Holy shit, serializing is way cool!

so FileStream works with BinaryFormatter, and NetworkStream works with StreamReader? Do i use BinaryReader to deserialize it?

I don't mean to be repetitive or annoying or anything but what is the purpose of NetworkStreamOwnsSocket, i don't understand it's purpose.



if (NetworkStreamOwnsSocket == true)
{
myNetworkStream = new NetworkStream(mySocket, true);
}
else if(NetworkStreamOwnsSocket == false)
{
myNetworkStream = new NetworkStream(mySocket, false);
}




Once again, not trying to be annoying.

I want to send the SOCKS Version 4 connect requrest to the server.

It consists of the following information:

BYTE: Version Number
BYTE: Command Code
WORD: Port
DWORD: IPAddress
STRING: UserId
BYTE: Null

How would i go about doing this? I don't want it done for me, but i don't know where to start either.

I Know i have to use the BitConverter Class



byte[] outBuf;

outBuf.CopyTo(BitConverter.Some Command);



I'm not sure what i use, or when to use it. 

Should i create seperate methods for Words, Double Words, Strings, Arrays of Words/DWords/Strings or should i just do it Locally?  I'm trying to find the Best/Most Efficient way to do it.

Thanks

- Joel
There are only two kinds of people who are really fascinating: people who know absolutely everything, and people who know absolutely nothing.

MyndFyre

Quote from: BaDDBLooD on January 31, 2006, 04:44 PM
so FileStream works with BinaryReader, and NetworkStream works with StreamReader?
Do you understand this syntax:

class A { int a; }
class B : A { int b; }

?

If so, then hopefully you'll understand this:

class Stream {}
class FileStream : Stream {}
class NetworkStream : Stream {}


For the first code, say you have this method:

void DoSomething(A blarg) { // stuff
}

Did you know you can make a B object, and since B is an A, you can pass that B object into that method?

Everything works on Stream.  That means if a FileStream IS a Stream, or a NetworkStream IS a Stream, then they'll work too.

All of those readers work on all of those streams!  That's what I'm trying to say!

Quote from: BaDDBLooD on January 31, 2006, 04:44 PM
I do't mean to be repetitive or annoying or anything but what is the purpose of NetworkStreamOwnsSocket, i don't understand it's purpose.
It's so the network stream knows whether it should close the socket or not when the network stream itself is closed (via .Close()).
Quote from: BaDDBLooD on January 31, 2006, 04:44 PM
BYTE: Version Number
BYTE: Command Code
WORD: Port
DWORD: IPAddress
STRING: UserId
BYTE: Null

How would i go about doing this? I don't want it done for me, but i don't know where to start either.
How about:
binaryWriter.Write(versionByte); // versionByte is a byte
binaryWriter.Write(commandCodeByte); // commandCodeByte is a byte
binaryWriter.Write(port); // port is a short
binaryWriter.Write(ipAddress.GetBytes()); // ipAddress is a System.Net.IPAddress
binaryWriter.Write(userName); // userName is a string
binaryWriter.Write((byte)0);


I'm not sure how BinaryWriter writes strings, so you might be better off with a simplified version of MBNCSUtil's DataBuffer class which allows you to specify how you want the string laid out (it looks like you'd want a C-style string).  Then you could do:

buffer += versionByte + commandCodeByte + port + ipAddress.GetBytes();
buffer.InsertCString(userName);
buffer.WriteToOutputStream(networkStream);

(Note that I overloaded the + operator for DataBuffer, that isn't usual for most .NET framework classes.  ;))
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

BaDDBLooD

So if Network Stream and FileStream are both streams and both are interchangeable, why do they have two? If StreamReader and BinaryReader both do the same thing, how do you know what one to use?
There are only two kinds of people who are really fascinating: people who know absolutely everything, and people who know absolutely nothing.

MyndFyre

Quote from: BaDDBLooD on January 31, 2006, 05:24 PM
So if Network Stream and FileStream are both streams and both are interchangeable, why do they have two? If StreamReader and BinaryReader both do the same thing, how do you know what one to use?
Because a NetworkStream is a stream that operates on a network, and FileStream is a stream that operates on a file.

Look at the methods of StreamReader and BinaryReader.  They don't do the same thing, they can just use the same things while they do what they do.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

BaDDBLooD

Quote from: MyndFyre on January 31, 2006, 06:08 PM
Quote from: BaDDBLooD on January 31, 2006, 05:24 PM
So if Network Stream and FileStream are both streams and both are interchangeable, why do they have two? If StreamReader and BinaryReader both do the same thing, how do you know what one to use?
Because a NetworkStream is a stream that operates on a network, and FileStream is a stream that operates on a file.

Look at the methods of StreamReader and BinaryReader.  They don't do the same thing, they can just use the same things while they do what they do.

Meh, i overcomplicated that to hell.  Anyways, i understand what your saying.

I manged to get sending down, and i am working on receiving.  I am using both your DataBuffer and DataBuffer classes.  I also decided to keep your Locales class not only because you had used it in your project, but because it just kicks ass lol, i never knew about that.  Imma use that in all my applications because of how sweet it is.

So i just leave your comments and what not in the files, and put your License along with my project or do i not need to do any of that?

Thanks a bunch rob, you rule.
There are only two kinds of people who are really fascinating: people who know absolutely everything, and people who know absolutely nothing.

MyndFyre

Quote from: BaDDBLooD on January 31, 2006, 07:56 PM
So i just leave your comments and what not in the files, and put your License along with my project or do i not need to do any of that?
The license and copyright notices need to stay in-place (as part of the license agreement IIRC), but you can do whatever you want with the comments.  They're there to generate the documentation webpages @ the MBNCSUtil website.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

BaDDBLooD

#10
What is the equivelents of inet_addr and htons in .NET?

EDIT

Quote from: BaDDBLooD on January 31, 2006, 09:33 PM
What is the equivelents of inet_addr and htons in .NET?

Found it on MSDN



myDataBuffer.InsertInt16(IPAddress.HostToNetworkOrder(p.Port));
myDataBuffer.InsertInt32(Convert.ToInt32(IPAddress.Parse(p.Server)));


There are only two kinds of people who are really fascinating: people who know absolutely everything, and people who know absolutely nothing.

BaDDBLooD

#11
Got another problem



public static void Main()
{
Test p = new Test();
p.Server = "211.143.183.66";
p.Port = 1080;
p.Type = 5;
p.UserID = "anonymous";

try
{
Socket mySocket;
if ((mySocket = Connect(p.Server, p.Port)) != null)
{
NetworkStream myNetworkStream = new NetworkStream(mySocket);

if (myNetworkStream.CanWrite == true)
{
StreamWriter myStreamWriter = new StreamWriter(myNetworkStream);
DataBuffer myDataBuffer = new DataBuffer();
if (p.Type == 4)
{
myDataBuffer.InsertByte(4);
myDataBuffer.InsertByte(1);
myDataBuffer.InsertInt16(IPAddress.HostToNetworkOrder(p.Port));
myDataBuffer.InsertInt32(Convert.ToInt32(IPAddress.Parse(p.Server)));
myDataBuffer.InsertCString(p.UserID);
}
else if (p.Type == 5)
{
myDataBuffer.InsertByte(5);
myDataBuffer.InsertByte(2);
myDataBuffer.InsertByte(0);
myDataBuffer.InsertByte(2);
}

myDataBuffer.WriteToOutputStream(myStreamWriter);

if (myNetworkStream.CanRead == true)
{
StreamReader myStreamReader = new StreamReader(myNetworkStream);
DataReader myDataReader = new DataReader(myStreamReader);]
}

}
else if (myNetworkStream.CanWrite == false)
{
Console.WriteLine("Network Stream is Not Writeable!");
}
}
}

catch (Exception e)
{
Console.WriteLine(e.ToString());
}

Console.ReadLine();
}



I get errors whenever i seem to reference my Stream Reader/Writer to one of the other classes in my project.

These are the errors i get:

Argument '1': cannot convert from 'System.IO.StreamReader' to 'System.IO.Stream'

Argument '1': cannot convert from 'System.IO.StreamWriter' to 'System.IO.Stream'

The best overloaded method match for 'Proxy.GUI.Console.DataBuffer.WriteToOutputStream(System.IO.Stream)' has some invalid arguments

The best overloaded method match for 'Proxy.GUI.Console.DataReader.DataReader(System.IO.Stream)' has some invalid arguments


Thank You For The Help

- Joel

EDIT: Well Figured it out

Stream Reader/Writer aren't actually streams, you gotta refer to their BaseStream property.
There are only two kinds of people who are really fascinating: people who know absolutely everything, and people who know absolutely nothing.