G
Grant Richard
Using the TcpListener and TcpClient I created a program that just sends and
receives a short string - over and over again. The program is fine until it
gets to around 1500 to 1800 messages. At that time, I get a SocketException
with the message "Only one usage of each socket address (protocol/network
address/port) is normally permitted". This happen if you use localhost or
between two distinct computers. And, for a period of time after the error
(~1 - 5 minutes), the program errors out on the first Client socket
connection.
The message is bogus since its works for the first 1000 or so times. It's
something else and the best it can do is this error. At first I thought is
was not destructing the connection but I explicitly called Dispose and also
garbage collected after every 500 connections - but that did not work.
I am using VS 2003 / .NET Framework 1.1. But, the same thing happens with
VS.NET and .NET FW 1.0. I searched google and the knowledge base but nothing
points to this error that was helpful.
Any advice or fix would be appreciated. The stripped down code is below.
Thanks in advance,
// code for NetStreamtest
using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Security.Permissions;
/***************************************************************
*
*
C:\Temp\vs.net\NetStreamTest\bin\Debug>netstreamtest localhost
Connecting to host->127.0.0.1
Number is 0 9/20/2003 3:19:15 PM
Number is 200 9/20/2003 3:19:15 PM
Number is 400 9/20/2003 3:19:16 PM
Number is 600 9/20/2003 3:19:16 PM
Number is 800 9/20/2003 3:19:17 PM
Number is 1000 9/20/2003 3:19:17 PM
Number is 1200 9/20/2003 3:19:18 PM
Number is 1400 9/20/2003 3:19:18 PM
Number is 1600 9/20/2003 3:19:19 PM
Number is 1800 9/20/2003 3:19:19 PM
CLIENT:Exception->System.Net.Sockets.SocketException: Only one usage of each
soc
ket address (protocol/network address/port) is normally permitted
at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port)
at System.Net.Sockets.TcpClient..ctor(String hostname, Int32 port)
at NetStreamTest.TCPCommunication.GoClient(String message) in
c:\temp\vs.net\
netstreamtest\netstreamtest.cs:line 109
Main:Exception at i =1961: System.Net.Sockets.SocketException: Only one
usage of
each socket address (protocol/network address/port) is normally permitted
at NetStreamTest.TCPCommunication.GoClient(String message) in
c:\temp\vs.net\
netstreamtest\netstreamtest.cs:line 123
at NetStreamTest.NetStreamTestMain.Main(String[] args) in
c:\temp\vs.net\nets
treamtest\netstreamtest.cs:line 35
Unhandled Exception: System.Net.Sockets.SocketException: Only one usage of
each
socket address (protocol/network address/port) is normally permitted
at NetStreamTest.NetStreamTestMain.Main(String[] args) in
c:\temp\vs.net\nets
treamtest\netstreamtest.cs:line 45
****************************************************************/
namespace NetStreamTest
{
class NetStreamTestMain
{
[STAThread]
static void Main(string[] args)
{
TCPCommunication tcc = null;
Thread th = null;
int i=0;
string s = "localhost";
if( args.Length > 0 )
if( args[0].Length > 0 )
s = args[0];
try
{
tcc = new TCPCommunication(s);
th = new Thread(new ThreadStart( tcc.GoServer ));
th.Start();
Thread.Sleep( 2 ); // wait for server to start...
for(i=0; i < 4000; i++) // it will fault before this is done
{
tcc.GoClient(i.ToString() + ":THIS IS A TEST ");
if( i % 200 == 0 ) // just so there is status
Console.Out.WriteLine("Number is " + i.ToString() + " " +
DateTime.Now.ToString() );
}
Thread.Sleep(2); // hopefully to clear out messages
}
catch (Exception e)
{
Console.WriteLine("Main:Exception at i ={0}: {1}", i ,e);
throw( e ); // re-throw the exception to end
}
finally
{
if( th != null )
th.Abort();
}
}
}
class TCPCommunication
{
private Int32 port = 812;
private bool DisplayItClient = false;
private bool DisplayItServer = false;
private string ServerName;
public TCPCommunication( string ServerName )
{
this.ServerName = ServerName;
}
[SocketPermission(SecurityAction.Demand, Unrestricted=true)]
public void GoServer()
{
bool notDone = true;
IPHostEntry heserver = Dns.Resolve(this.ServerName);
Console.Out.WriteLine("Connecting to host->" +
heserver.AddressList[0].ToString() );
TcpListener server = new TcpListener( heserver.AddressList[0], port);
server.Start();
if( this.DisplayItServer )
Console.Out.WriteLine("In GoServer thread");
while( notDone )
{
try
{
Socket s = server.AcceptSocket();
NetworkStream stream = new NetworkStream( s );
string response = this.ReadMessage(stream, this.DisplayItServer);
this.WriteMessage(response+" ***** GOT IT! ***** ", stream ,
this.DisplayItServer);
if( this.DisplayItServer )
Console.Out.WriteLine("SERVER: response = " + response);
}
catch (Exception e)
{
Console.WriteLine("SERVER:Exception-> {0}", e);
notDone = false;
}
}
server.Stop();
}
public void GoClient(string message )
{
try
{
if( this.DisplayItClient )
Console.Out.WriteLine("CLIENT:Msg"+message);
TcpClient client = new TcpClient(this.ServerName, port);
NetworkStream stream = client.GetStream();
this.WriteMessage(message,stream,this.DisplayItClient);
string response = this.ReadMessage(stream,this.DisplayItClient);
if( this.DisplayItClient )
Console.Out.WriteLine("response = "+response);
// Close everything.
client.Close();
}
catch (Exception e)
{
Console.WriteLine("CLIENT:Exception->{0}", e);
throw( e );
}
}
void WriteMessage( string message, NetworkStream ns, bool log )
{
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Send the message to the connected TcpServer.
ns.Write(data, 0, data.Length);
if( log )
Console.WriteLine("Sent: {0}", message);
}
string ReadMessage( NetworkStream ns, bool log )
{
// Buffer to store the response bytes.
Byte [] data = new Byte[512];
// String to store the response ASCII representation
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = ns.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
if( log )
Console.WriteLine("Sent: {0}", responseData);
return responseData;
}
}
}
receives a short string - over and over again. The program is fine until it
gets to around 1500 to 1800 messages. At that time, I get a SocketException
with the message "Only one usage of each socket address (protocol/network
address/port) is normally permitted". This happen if you use localhost or
between two distinct computers. And, for a period of time after the error
(~1 - 5 minutes), the program errors out on the first Client socket
connection.
The message is bogus since its works for the first 1000 or so times. It's
something else and the best it can do is this error. At first I thought is
was not destructing the connection but I explicitly called Dispose and also
garbage collected after every 500 connections - but that did not work.
I am using VS 2003 / .NET Framework 1.1. But, the same thing happens with
VS.NET and .NET FW 1.0. I searched google and the knowledge base but nothing
points to this error that was helpful.
Any advice or fix would be appreciated. The stripped down code is below.
Thanks in advance,
// code for NetStreamtest
using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Security.Permissions;
/***************************************************************
*
*
C:\Temp\vs.net\NetStreamTest\bin\Debug>netstreamtest localhost
Connecting to host->127.0.0.1
Number is 0 9/20/2003 3:19:15 PM
Number is 200 9/20/2003 3:19:15 PM
Number is 400 9/20/2003 3:19:16 PM
Number is 600 9/20/2003 3:19:16 PM
Number is 800 9/20/2003 3:19:17 PM
Number is 1000 9/20/2003 3:19:17 PM
Number is 1200 9/20/2003 3:19:18 PM
Number is 1400 9/20/2003 3:19:18 PM
Number is 1600 9/20/2003 3:19:19 PM
Number is 1800 9/20/2003 3:19:19 PM
CLIENT:Exception->System.Net.Sockets.SocketException: Only one usage of each
soc
ket address (protocol/network address/port) is normally permitted
at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port)
at System.Net.Sockets.TcpClient..ctor(String hostname, Int32 port)
at NetStreamTest.TCPCommunication.GoClient(String message) in
c:\temp\vs.net\
netstreamtest\netstreamtest.cs:line 109
Main:Exception at i =1961: System.Net.Sockets.SocketException: Only one
usage of
each socket address (protocol/network address/port) is normally permitted
at NetStreamTest.TCPCommunication.GoClient(String message) in
c:\temp\vs.net\
netstreamtest\netstreamtest.cs:line 123
at NetStreamTest.NetStreamTestMain.Main(String[] args) in
c:\temp\vs.net\nets
treamtest\netstreamtest.cs:line 35
Unhandled Exception: System.Net.Sockets.SocketException: Only one usage of
each
socket address (protocol/network address/port) is normally permitted
at NetStreamTest.NetStreamTestMain.Main(String[] args) in
c:\temp\vs.net\nets
treamtest\netstreamtest.cs:line 45
****************************************************************/
namespace NetStreamTest
{
class NetStreamTestMain
{
[STAThread]
static void Main(string[] args)
{
TCPCommunication tcc = null;
Thread th = null;
int i=0;
string s = "localhost";
if( args.Length > 0 )
if( args[0].Length > 0 )
s = args[0];
try
{
tcc = new TCPCommunication(s);
th = new Thread(new ThreadStart( tcc.GoServer ));
th.Start();
Thread.Sleep( 2 ); // wait for server to start...
for(i=0; i < 4000; i++) // it will fault before this is done
{
tcc.GoClient(i.ToString() + ":THIS IS A TEST ");
if( i % 200 == 0 ) // just so there is status
Console.Out.WriteLine("Number is " + i.ToString() + " " +
DateTime.Now.ToString() );
}
Thread.Sleep(2); // hopefully to clear out messages
}
catch (Exception e)
{
Console.WriteLine("Main:Exception at i ={0}: {1}", i ,e);
throw( e ); // re-throw the exception to end
}
finally
{
if( th != null )
th.Abort();
}
}
}
class TCPCommunication
{
private Int32 port = 812;
private bool DisplayItClient = false;
private bool DisplayItServer = false;
private string ServerName;
public TCPCommunication( string ServerName )
{
this.ServerName = ServerName;
}
[SocketPermission(SecurityAction.Demand, Unrestricted=true)]
public void GoServer()
{
bool notDone = true;
IPHostEntry heserver = Dns.Resolve(this.ServerName);
Console.Out.WriteLine("Connecting to host->" +
heserver.AddressList[0].ToString() );
TcpListener server = new TcpListener( heserver.AddressList[0], port);
server.Start();
if( this.DisplayItServer )
Console.Out.WriteLine("In GoServer thread");
while( notDone )
{
try
{
Socket s = server.AcceptSocket();
NetworkStream stream = new NetworkStream( s );
string response = this.ReadMessage(stream, this.DisplayItServer);
this.WriteMessage(response+" ***** GOT IT! ***** ", stream ,
this.DisplayItServer);
if( this.DisplayItServer )
Console.Out.WriteLine("SERVER: response = " + response);
}
catch (Exception e)
{
Console.WriteLine("SERVER:Exception-> {0}", e);
notDone = false;
}
}
server.Stop();
}
public void GoClient(string message )
{
try
{
if( this.DisplayItClient )
Console.Out.WriteLine("CLIENT:Msg"+message);
TcpClient client = new TcpClient(this.ServerName, port);
NetworkStream stream = client.GetStream();
this.WriteMessage(message,stream,this.DisplayItClient);
string response = this.ReadMessage(stream,this.DisplayItClient);
if( this.DisplayItClient )
Console.Out.WriteLine("response = "+response);
// Close everything.
client.Close();
}
catch (Exception e)
{
Console.WriteLine("CLIENT:Exception->{0}", e);
throw( e );
}
}
void WriteMessage( string message, NetworkStream ns, bool log )
{
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
// Send the message to the connected TcpServer.
ns.Write(data, 0, data.Length);
if( log )
Console.WriteLine("Sent: {0}", message);
}
string ReadMessage( NetworkStream ns, bool log )
{
// Buffer to store the response bytes.
Byte [] data = new Byte[512];
// String to store the response ASCII representation
String responseData = String.Empty;
// Read the first batch of the TcpServer response bytes.
Int32 bytes = ns.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
if( log )
Console.WriteLine("Sent: {0}", responseData);
return responseData;
}
}
}