NegotiateStream problem?

I have this code where I would like to authenticate before starting to accept communications from a client. After I add the authentication code, I stop getting the actual data. Here is the code. What is wrong?

using System;

using System.Net;

using System.Net.Sockets;

using System.Net.Security;

using System.Text;

using System.Threading;

namespace TestApp

{

classClass1 {

[STAThread]

staticvoid Main(string[] args) {

try {

ThreadStart threadStart =new ThreadStart(StartServer);

Thread processThread =newThread(threadStart);

processThread.Start();

ClientTest();

}

catch (ArgumentNullException e) {

Console.WriteLine("ArgumentNullException: {0}", e);

}

catch (SocketException e) {

Console.WriteLine("SocketException: {0}", e);

}

}

privatestaticbool ServerReady =false;

privatestatic Int32 port = 11000;

privatestaticstring hostName =Dns.GetHostName();

privatestaticvoid ClientTest()

{

while (!ServerReady)

Thread.Sleep(1000);

ServerReady =false;

TcpClient client =newTcpClient(hostName, port);

client.LingerState =newLingerOption(true, 0);

Byte[] data = System.Text.Encoding.ASCII.GetBytes("Testing...");

NetworkStream stream = client.GetStream();

NegotiateStream authStream =newNegotiateStream(stream,true);

authStream.AuthenticateAsClient();

if (!authStream.IsAuthenticated)

thrownewApplicationException("Failed to authenticate!");

authStream.Close();

stream.Write(data, 0, data.Length);

Console.WriteLine("Sent: {0}",Encoding.ASCII.GetString(data));

client.Close();

while (!ServerReady)

Thread.Sleep(1000);

}

privatestaticvoid StartServer()

{

IPAddress localAddress;

TcpListener Server;

localAddress =Dns.GetHostEntry(hostName).AddressList[0];

Server =newTcpListener(localAddress, port);

Server.Start();

ServerReady =true;

TcpClient client = Server.AcceptTcpClient();

NetworkStream stream = client.GetStream();

NegotiateStream authStream =newNegotiateStream(stream,true);

authStream.AuthenticateAsServer();

if (!authStream.IsAuthenticated)

thrownewApplicationException("Failed to authenticate!");

authStream.Close();

byte[] buffer =newbyte[256];

int bytesRead;

StringBuilder data =newStringBuilder();

while (stream.DataAvailable)

{

bytesRead = stream.Read(buffer, 0, buffer.Length);

data.Append(Encoding.ASCII.GetString(buffer, 0, bytesRead));

}

Console.WriteLine("Received:" + data.ToString());

ServerReady =true;

}

}

}

Thanks.

James

[8552 byte] By [james_paul_p] at [2007-12-18]
# 1

You have closed the AuthStream.

DurgaprasadGorti at 2007-9-8 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 2
I had passed "true" as the value for second argument to the constructor. I have commented the close the statement and the results are same.
james_paul_p at 2007-9-8 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 3

Although you are creating an authStream object, you are doing your read/write operations on the NetworkStream object. You should be reading/writing from the NegotiateStream object, not the NetworkStream object.

This is what you have, Notice that you are calling 'stream.Write' instead of 'authStream.Write'. Also, as Durga mentioned, you shouldn't be closing the authStream object.

NetworkStream stream = client.GetStream();

NegotiateStream authStream = new NegotiateStream(stream, true);

authStream.AuthenticateAsClient();

if (!authStream.IsAuthenticated)

throw new ApplicationException("Failed to authenticate!");

authStream.Close();

stream.Write(data, 0, data.Length);

JonCole at 2007-9-8 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 4

Thanks, but I still have the same problem.

What I did:

1. Changed the read and write using NegotiateStream object. NegotiateStream does not have a DataAvailable property so I still have to use NetworkStream for that purpose.

2. Removed all closing of the streams.

using System;

using System.Net;

using System.Net.Sockets;

using System.Net.Security;

using System.Text;

using System.Threading;

namespace TestApp

{

class Class1 {

[STAThread]

static void Main(string[] args) {

try {

ThreadStart threadStart = new ThreadStart(StartServer);

Thread processThread = new Thread(threadStart);

processThread.Start();

ClientTest();

}

catch (ArgumentNullException e) {

Console.WriteLine("ArgumentNullException: {0}", e);

}

catch (SocketException e) {

Console.WriteLine("SocketException: {0}", e);

}

}

private static bool ServerReady = false;

private static Int32 port = 11000;

private static string hostName = Dns.GetHostName();

private static void ClientTest()

{

while (!ServerReady)

Thread.Sleep(1000);

ServerReady = false;

TcpClient client = new TcpClient(hostName, port);

client.LingerState = new LingerOption(true, 0);

Byte[] data = System.Text.Encoding.ASCII.GetBytes("Testing...");

NetworkStream stream = client.GetStream();

NegotiateStream authStream = new NegotiateStream(stream, true);

authStream.AuthenticateAsClient();

if (!authStream.IsAuthenticated)

throw new ApplicationException("Failed to authenticate!");

authStream.Write(data, 0, data.Length);

Console.WriteLine("Sent: {0}", Encoding.ASCII.GetString(data));

client.Close();

while (!ServerReady)

Thread.Sleep(1000);

}

private static void StartServer()

{

IPAddress localAddress;

TcpListener Server;

localAddress = Dns.GetHostEntry(hostName).AddressList[0];

Server = new TcpListener(localAddress, port);

Server.Start();

ServerReady = true;

TcpClient client = Server.AcceptTcpClient();

NetworkStream stream = client.GetStream();

NegotiateStream authStream = new NegotiateStream(stream, true);

authStream.AuthenticateAsServer();

if (!authStream.IsAuthenticated)

throw new ApplicationException("Failed to authenticate!");

byte[] buffer = new byte[256];

int bytesRead;

StringBuilder data = new StringBuilder();

while (stream.DataAvailable)

{

bytesRead = authStream.Read(buffer, 0, buffer.Length);

data.Append(Encoding.ASCII.GetString(buffer, 0, bytesRead));

}

Console.WriteLine("Received:" + data.ToString());

ServerReady = true;

}

}

}

james_paul_p at 2007-9-8 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 5

The server is exiting even before the data is available.

Look at this fixed version

using System;

using System.Net;

using System.Net.Sockets;

using System.Net.Security;

using System.Text;

using System.Threading;

namespace TestApp

{

class Class1 {

private static bool ServerReady = false;

private static Int32 port = 11000;

private static string hostName = Dns.GetHostName();

static void Main(string[] args) {

try {

ThreadStart threadStart = new ThreadStart(StartServer);

Thread processThread = new Thread(threadStart);

processThread.Start();

ClientTest();

}

catch (ArgumentNullException e) {

Console.WriteLine("ArgumentNullException: {0}", e);

}

catch (SocketException e) {

Console.WriteLine("SocketException: {0}", e);

}

}

private static void ClientTest()

{

while (!ServerReady)

Thread.Sleep(1000);

ServerReady = false;

TcpClient client = new TcpClient(hostName, port);

// client.LingerState = new LingerOption(true, 0);

Byte[] data = System.Text.Encoding.ASCII.GetBytes("Testing...");

NetworkStream stream = client.GetStream();

NegotiateStream authStream = new NegotiateStream(stream, true);

authStream.AuthenticateAsClient();

if (!authStream.IsAuthenticated)

throw new ApplicationException("Failed to authenticate!");

authStream.Write(data, 0, data.Length);

Console.WriteLine("Sent: {0}", Encoding.ASCII.GetString(data));

client.Close();

while (!ServerReady)

Thread.Sleep(1000);

}

private static void StartServer()

{

IPAddress localAddress;

TcpListener Server;

localAddress = Dns.GetHostEntry(hostName).AddressList[0];

Server = new TcpListener(localAddress, port);

Server.Start();

ServerReady = true;

TcpClient client = Server.AcceptTcpClient();

NetworkStream stream = client.GetStream();

NegotiateStream authStream = new NegotiateStream(stream, true);

authStream.AuthenticateAsServer();

if (!authStream.IsAuthenticated)

throw new ApplicationException("Failed to authenticate!");

byte[] buffer = new byte[256];

int bytesRead;

StringBuilder data = new StringBuilder();

bytesRead = authStream.Read(buffer, 0, buffer.Length);

while (bytesRead > 0)

{

data.Append(Encoding.ASCII.GetString(buffer, 0, bytesRead));

bytesRead = authStream.Read(buffer, 0, buffer.Length);

}

Console.WriteLine("Received:" + data.ToString());

ServerReady = true;

}

}

}

DurgaprasadGorti at 2007-9-8 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 6

Thanks Durga. That was it.

Issues in my code were:

1. Closed the stream at server end.

2. Did not use NegotiateStream for reading and writing.

3. While loop reading from stream was inaccurate because of use of DataAvailable property of NetworkStream.

Things that did not make difference in resolving the issue:

1. LingerState

2. STAThread attribute

Thanks.

James

james_paul_p at 2007-9-8 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...
# 7

Personally I think it is totally idiotic for VS to
generate [STA...] attribute. It means nothing in most cases and confuses people that thare is something going on ....

Good luck

DurgaprasadGorti at 2007-9-8 > top of Msdn Tech,.NET Development,.NET Framework Networking and Communication...

.NET Development

Site Classified