asynchronous socket problem when connecting to localhost

D

darthghandi

I am trying to create a server application using asynchronous
sockets. I run into a problem when I try to connect to my server
using a non-.net program. I can establish the connection, and send
some packets in response to the programs first message, but when I
receive a response back, it's the last packet I sent. After that
packet, I receive the packet I really wanted. This only happens when
I connect with local host. I tried connecting with that same program
from another computer, and there is no problem. Any ideas?
Thanks,
Chris

Here's some of the code:
public void Bind(int l_port)
{;
m_port = l_port;
IPHostEntry ipHostInfo = Dns.GetHostEntry("");
IPAddress ipAddress = ipHostInfo.AddressList[1];
//m_tcpEndPoint = new IPEndPoint(IPAddress.Any, m_port);
m_tcpEndPoint = new IPEndPoint(ipAddress, m_port);
m_mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
m_mainSocket.Bind(m_tcpEndPoint);
m_mainSocket.Listen(100);
m_callBack = new AsyncCallback(OnClientConnect);
m_mainSocket.BeginAccept(m_callBack, m_mainSocket);
}
public void OnClientConnect(IAsyncResult ar)
{
try
{
Socket stateOfRecieveSock = (Socket)ar.AsyncState;
m_workSocks[sockCount] =
stateOfRecieveSock.EndAccept(ar);
OnSend(m_workSocks[sockCount]);
sockCount++;
AsyncCallback recievedData = new
AsyncCallback(OnClientConnect);
stateOfRecieveSock.BeginAccept(recievedData,
stateOfRecieveSock);
}
catch (Exception ex)
{
throw new Exception("There was a problem receiving
data.", ex);
}
}
//SendMessage is called after receiving a packet from the
client and sending one as well

public void SendMessage(IOBuffer stateOfTheSock)
{
if (stateOfTheSock.TheSocket.Connected)
{
//add data to the buffer
AsyncCallback callMe = new
AsyncCallback(GotMoreData);

stateOfTheSock.TheSocket.BeginSend(stateOfTheSock.TheBuffer, 0,
stateOfTheSock.TheBuffer.Length, SocketFlags.None, callMe,
stateOfTheSock);
}
public void GotMoreData(IAsyncResult ar)
{
IOBuffer moreSocks = (IOBuffer)ar.AsyncState;
if (moreSocks.TheSocket.Connected)
{
moreSocks.BytesReceived =
moreSocks.TheSocket.EndReceive(ar);
moreSocks.ClearBuffer();
AsyncCallback more = new AsyncCallback(GotMoreData);
moreSocks.TheSocket.BeginReceive(moreSocks.TheBuffer,
0, moreSocks.TheBuffer.Length, SocketFlags.None, more, moreSocks);
}
}
 
M

Michael Rubinstein

Chris, server talking to itself?
You server starts sending right after accepting connection. It is
unusual.Normally a client would send something upon connection to indicate
it is ready, the server would respond after receiving some data. This will
also ensure the packet goes to a correct client.

Michael
 
D

darthghandi

Chris, server talking to itself?
You server starts sending right after accepting connection. It is
unusual.Normally a client would send something upon connection to indicate
it is ready, the server would respond after receiving some data. This will
also ensure the packet goes to a correct client.

Michael


I am trying to create a server application using asynchronous
sockets. I run into a problem when I try to connect to my server
using a non-.net program. I can establish the connection, and send
some packets in response to the programs first message, but when I
receive a response back, it's the last packet I sent. After that
packet, I receive the packet I really wanted. This only happens when
I connect with local host. I tried connecting with that same program
from another computer, and there is no problem. Any ideas?
Thanks,
Chris
Here's some of the code:
public void Bind(int l_port)
{;
m_port = l_port;
IPHostEntry ipHostInfo = Dns.GetHostEntry("");
IPAddress ipAddress = ipHostInfo.AddressList[1];
//m_tcpEndPoint = new IPEndPoint(IPAddress.Any, m_port);
m_tcpEndPoint = new IPEndPoint(ipAddress, m_port);
m_mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
m_mainSocket.Bind(m_tcpEndPoint);
m_mainSocket.Listen(100);
m_callBack = new AsyncCallback(OnClientConnect);
m_mainSocket.BeginAccept(m_callBack, m_mainSocket);
}
public void OnClientConnect(IAsyncResult ar)
{
try
{
Socket stateOfRecieveSock = (Socket)ar.AsyncState;
m_workSocks[sockCount] =
stateOfRecieveSock.EndAccept(ar);
OnSend(m_workSocks[sockCount]);
sockCount++;
AsyncCallback recievedData = new
AsyncCallback(OnClientConnect);
stateOfRecieveSock.BeginAccept(recievedData,
stateOfRecieveSock);
}
catch (Exception ex)
{
throw new Exception("There was a problem receiving
data.", ex);
}
}
//SendMessage is called after receiving a packet from the
client and sending one as well
public void SendMessage(IOBuffer stateOfTheSock)
{
if (stateOfTheSock.TheSocket.Connected)
{
//add data to the buffer
AsyncCallback callMe = new
AsyncCallback(GotMoreData);
stateOfTheSock.TheSocket.BeginSend(stateOfTheSock.TheBuffer, 0,
stateOfTheSock.TheBuffer.Length, SocketFlags.None, callMe,
stateOfTheSock);
}
public void GotMoreData(IAsyncResult ar)
{
IOBuffer moreSocks = (IOBuffer)ar.AsyncState;
if (moreSocks.TheSocket.Connected)
{
moreSocks.BytesReceived =
moreSocks.TheSocket.EndReceive(ar);
moreSocks.ClearBuffer();
AsyncCallback more = new AsyncCallback(GotMoreData);
moreSocks.TheSocket.BeginReceive(moreSocks.TheBuffer,
0, moreSocks.TheBuffer.Length, SocketFlags.None, more, moreSocks);
}
}

That was my first thought as well. I am trying to create a server for
an already built client (weird I know, but it's for school and I just
do what I'm told). I tried making the server complete the TCP
connection and then wait for the client to send what it's supposed to
send, but I just keep waiting for it. That's when I tried to send the
info I'm supposed to send first, then listen for the response. That
works at first, then I run into the problem listed above. Maybe I'll
try sending one then waiting for another before I send one again.
We'll see if that works.
On another note, does anyone know how to listen on localhost and all
the given IP's all at once? The only way I have found to do this is
to use IPAdress.Any, but I heard that this wasn't secure. Don't know
much about that. If anyone has any info an that, please share.
Thanks,
Chris
 
M

Michael Rubinstein

Chris, if your client is not correctly written, then there is so much
you can do. The TCP connection is established once the client receives the
CallBack from BeginConnect() or whatever Winsock code it uses. At that point
the client can issue Send() or BeginSend().On another note, does anyone know how to listen on localhost and all
the given IP's all at once? The only way I have found to do this is
to use IPAdress.Any, but I heard that this wasn't secure.If you are concerned about security then the firewall is a better place to
address it.

Good luck, Michael


Chris, server talking to itself?
You server starts sending right after accepting connection. It is
unusual.Normally a client would send something upon connection to indicate
it is ready, the server would respond after receiving some data. This will
also ensure the packet goes to a correct client.

Michael


I am trying to create a server application using asynchronous
sockets. I run into a problem when I try to connect to my server
using a non-.net program. I can establish the connection, and send
some packets in response to the programs first message, but when I
receive a response back, it's the last packet I sent. After that
packet, I receive the packet I really wanted. This only happens when
I connect with local host. I tried connecting with that same program
from another computer, and there is no problem. Any ideas?
Thanks,
Chris
Here's some of the code:
public void Bind(int l_port)
{;
m_port = l_port;
IPHostEntry ipHostInfo = Dns.GetHostEntry("");
IPAddress ipAddress = ipHostInfo.AddressList[1];
//m_tcpEndPoint = new IPEndPoint(IPAddress.Any, m_port);
m_tcpEndPoint = new IPEndPoint(ipAddress, m_port);
m_mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
m_mainSocket.Bind(m_tcpEndPoint);
m_mainSocket.Listen(100);
m_callBack = new AsyncCallback(OnClientConnect);
m_mainSocket.BeginAccept(m_callBack, m_mainSocket);
}
public void OnClientConnect(IAsyncResult ar)
{
try
{
Socket stateOfRecieveSock = (Socket)ar.AsyncState;
m_workSocks[sockCount] =
stateOfRecieveSock.EndAccept(ar);
OnSend(m_workSocks[sockCount]);
sockCount++;
AsyncCallback recievedData = new
AsyncCallback(OnClientConnect);
stateOfRecieveSock.BeginAccept(recievedData,
stateOfRecieveSock);
}
catch (Exception ex)
{
throw new Exception("There was a problem receiving
data.", ex);
}
}
//SendMessage is called after receiving a packet from the
client and sending one as well
public void SendMessage(IOBuffer stateOfTheSock)
{
if (stateOfTheSock.TheSocket.Connected)
{
//add data to the buffer
AsyncCallback callMe = new
AsyncCallback(GotMoreData);
stateOfTheSock.TheSocket.BeginSend(stateOfTheSock.TheBuffer, 0,
stateOfTheSock.TheBuffer.Length, SocketFlags.None, callMe,
stateOfTheSock);
}
public void GotMoreData(IAsyncResult ar)
{
IOBuffer moreSocks = (IOBuffer)ar.AsyncState;
if (moreSocks.TheSocket.Connected)
{
moreSocks.BytesReceived =
moreSocks.TheSocket.EndReceive(ar);
moreSocks.ClearBuffer();
AsyncCallback more = new AsyncCallback(GotMoreData);
moreSocks.TheSocket.BeginReceive(moreSocks.TheBuffer,
0, moreSocks.TheBuffer.Length, SocketFlags.None, more, moreSocks);
}
}

That was my first thought as well. I am trying to create a server for
an already built client (weird I know, but it's for school and I just
do what I'm told). I tried making the server complete the TCP
connection and then wait for the client to send what it's supposed to
send, but I just keep waiting for it. That's when I tried to send the
info I'm supposed to send first, then listen for the response. That
works at first, then I run into the problem listed above. Maybe I'll
try sending one then waiting for another before I send one again.
We'll see if that works.
On another note, does anyone know how to listen on localhost and all
the given IP's all at once? The only way I have found to do this is
to use IPAdress.Any, but I heard that this wasn't secure. Don't know
much about that. If anyone has any info an that, please share.
Thanks,
Chris
 
P

Peter Duniho

[...]
On another note, does anyone know how to listen on localhost and all
the given IP's all at once? The only way I have found to do this is
to use IPAdress.Any, but I heard that this wasn't secure. Don't know
much about that. If anyone has any info an that, please share.

I don't see why using "any" for your IP address is inherently any less
secure than using a specific IP address. And it's the only way for you to
allow a single socket to accept connections on more than one IP address.
 
C

Chris Mullins [MVP]

Peter Duniho said:
[...]
On another note, does anyone know how to listen on localhost and all
the given IP's all at once? The only way I have found to do this is
to use IPAdress.Any, but I heard that this wasn't secure. Don't know
much about that. If anyone has any info an that, please share.

I don't see why using "any" for your IP address is inherently any less
secure than using a specific IP address. And it's the only way for you to
allow a single socket to accept connections on more than one IP address.

I agree - the only time using "Any" (0.0.0.0) would be insecure is when one
of your IP Addresses is considered insecure. For example, often I want to
start a service process up (say, IIS for testing) and have it ONLY listen on
127.0.0.1 - this helps mitigate the threat surface.

If I have IIS listen on my main ip (192.168.100.100, say), then I'm now
allowing anyone to come attack it.

If the goal is to have my socket app listen on all sockets, then there's no
security difference that I can see between binding to the "any" address, or
enumerating the addresses and binding to each invividually.
 
D

darthghandi

[...]
On another note, does anyone know how to listen on localhost and all
the given IP's all at once? The only way I have found to do this is
to use IPAdress.Any, but I heard that this wasn't secure. Don't know
much about that. If anyone has any info an that, please share.
I don't see why using "any" for your IP address is inherently any less
secure than using a specific IP address. And it's the only way for you to
allow a single socket to accept connections on more than one IP address.

I agree - the only time using "Any" (0.0.0.0) would be insecure is when one
of your IP Addresses is considered insecure. For example, often I want to
start a service process up (say, IIS for testing) and have it ONLY listen on
127.0.0.1 - this helps mitigate the threat surface.

If I have IIS listen on my main ip (192.168.100.100, say), then I'm now
allowing anyone to come attack it.

If the goal is to have my socket app listen on all sockets, then there's no
security difference that I can see between binding to the "any" address, or
enumerating the addresses and binding to each invividually.

Thanks for the help. I solved the problem by sending ignored data
inbetween recieves. I was just wondering if anyone knew of anything I
should look out for when doing this.
Thanks,
 
P

Peter Duniho

Thanks for the help. I solved the problem by sending ignored data
inbetween recieves. I was just wondering if anyone knew of anything I
should look out for when doing this.

Yes. Sending extra "ignored data" is a hack and there's no reason you
should need to do it. If you do, it means you have an unsolved bug in
your own code. Adding a new bug to your code in order to avoid a
different bug already in your code is not a good programming practice.

Pete
 
D

darthghandi

Yes. Sending extra "ignored data" is a hack and there's no reason you
should need to do it. If you do, it means you have an unsolved bug in
your own code. Adding a new bug to your code in order to avoid a
different bug already in your code is not a good programming practice.

Pete

After many moons, I found my unsolved bug. It seems the socket had
already given me the packet I was looking for combined with the
earlier packet. I had (wrongly) assumed that when I did a
BeginRecieve(), I would just get one message in the buffer instead of
two. Now I am rewriting the code to support multiple messages in one
buffer.
Thanks again for your time,
Chris
 
J

JR

Sockets send and receive bytes, not messages. This is a common mistake. The
receiver needs to split the byte stream into messages.

In practive, for shorter messages with some delay between them, you will
often receive complete messages each time.

JR
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top