472,799 Members | 1,390 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,799 software developers and data experts.

Reading data on Aysnchronous socket server

Hi,

I have a synchronous socket server which my app uses to read data from
clients.

To test this I have a simulated client that sends 100 byte packets.

I have set up the socket server so that its buffer is bigger than this.
I did this expecting the data to be read in one pass.

However what I find is that on the first pass it only reads the first 4
bytes and then on the second pass of begin.receive, reads the rest of the
message. Is this usual?

This happens each time I send my packet from the
The code I have been using is the MSDN example( shown below).

Can anyone tell me if it is possible to read the whole message sent form the
client on the first pass rather than it taking 2 or more passes?

Thanks
Macca
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

// State object for reading client data asynchronously
public class StateObject {
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 100;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}

public class AsynchronousSocketListener {
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);

public AsynchronousSocketListener() {
}

public static void StartListening() {
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];

// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
SN.IPHostEntry ipHostInfo = SN.Dns.GetHostEntry(hostname);
SN.IPAddress ipAddress = ipHostInfo.AddressList[0];
SN.IPEndPoint localEndPoint = new SN.IPEndPoint(ipAddress, 7777);

// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );

// Bind the socket to the local endpoint and listen for incoming
connections.
try {
listener.Bind(localEndPoint);
listener.Listen(100);

while (true) {
// Set the event to nonsignaled state.
allDone.Reset();

// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener );

// Wait until a connection is made before continuing.
allDone.WaitOne();
}

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

Console.WriteLine("\nPress ENTER to continue...");
Console.Read();

}

public static void AcceptCallback(IAsyncResult ar) {
// Signal the main thread to continue.
allDone.Set();

// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);

// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}

public static void ReadCallback(IAsyncResult ar) {
String content = String.Empty;

// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;

// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);

if (bytesRead > 0) {
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));

// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1) {
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content );
// Echo the data back to the client.
Send(handler, content);
} else {
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0,
StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}

private static void Send(Socket handler, String data) {
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);

// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}

private static void SendCallback(IAsyncResult ar) {
try {
// Retrieve the socket from the state object.
Socket handler = (Socket) ar.AsyncState;

// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);

handler.Shutdown(SocketShutdown.Both);
handler.Close();

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

Feb 16 '06 #1
9 3488
Macca,

I don't believe it is possible. Rather, you should store the bytes that
are read in a buffer somewhere, and read again until you have the contents
of the message that you are trying to read. If you know your message is
going to be a certain length, then you can indicate how many bytes you want
to read in the call to Receive/BeginReceive. Then, when you issue the next
call, you can decrement the number of bytes you need to read.

For example, if you know your message is 100 bytes long, and the first
call to Receive/BeginReceive returns 4 bytes, then the next call can be for
96 bytes.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Macca" <Ma***@discussions.microsoft.com> wrote in message
news:E4**********************************@microsof t.com...
Hi,

I have a synchronous socket server which my app uses to read data from
clients.

To test this I have a simulated client that sends 100 byte packets.

I have set up the socket server so that its buffer is bigger than this.
I did this expecting the data to be read in one pass.

However what I find is that on the first pass it only reads the first 4
bytes and then on the second pass of begin.receive, reads the rest of the
message. Is this usual?

This happens each time I send my packet from the
The code I have been using is the MSDN example( shown below).

Can anyone tell me if it is possible to read the whole message sent form
the
client on the first pass rather than it taking 2 or more passes?

Thanks
Macca
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

// State object for reading client data asynchronously
public class StateObject {
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 100;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}

public class AsynchronousSocketListener {
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);

public AsynchronousSocketListener() {
}

public static void StartListening() {
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];

// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
SN.IPHostEntry ipHostInfo = SN.Dns.GetHostEntry(hostname);
SN.IPAddress ipAddress = ipHostInfo.AddressList[0];
SN.IPEndPoint localEndPoint = new SN.IPEndPoint(ipAddress,
7777);

// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );

// Bind the socket to the local endpoint and listen for incoming
connections.
try {
listener.Bind(localEndPoint);
listener.Listen(100);

while (true) {
// Set the event to nonsignaled state.
allDone.Reset();

// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener );

// Wait until a connection is made before continuing.
allDone.WaitOne();
}

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

Console.WriteLine("\nPress ENTER to continue...");
Console.Read();

}

public static void AcceptCallback(IAsyncResult ar) {
// Signal the main thread to continue.
allDone.Set();

// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);

// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}

public static void ReadCallback(IAsyncResult ar) {
String content = String.Empty;

// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;

// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);

if (bytesRead > 0) {
// There might be more data, so store the data received so
far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));

// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1) {
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data :
{1}",
content.Length, content );
// Echo the data back to the client.
Send(handler, content);
} else {
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0,
StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}

private static void Send(Socket handler, String data) {
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);

// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}

private static void SendCallback(IAsyncResult ar) {
try {
// Retrieve the socket from the state object.
Socket handler = (Socket) ar.AsyncState;

// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);

handler.Shutdown(SocketShutdown.Both);
handler.Close();

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

Feb 16 '06 #2
You probably can but I don't think is safe unless you know the exact
length of the pakets sent to you.
I would use, and as a matter of fact I do use, a loop and bytes why
there's still some.
After that I close the stream.

I don't have an example right here so if you need one tell me and'll
look for it.

Regards.
Seba

-----
http://sgomez.blogspot.com

Feb 16 '06 #3
You must always *expect you will get 1 or more bytes (or 0 if shutdown by
sender) upto max of Count bytes. That is all you can expect and you need to
design your logic always with that understanding. The sender may be sending
4 bytes (maybe a length) as one Send and then sending the data as the second
Send(). This could be because they wanted to save a buffer copy to join the
two arrays. On the other hand, that could make less efficient network
traffic if it means the first send/ack will always be only 4 bytes. So do
you pay the price in the buffer join(s) or slightly more traffic. Can't
really say as it depends on the app, net speed, etc.

--
William Stacey [MVP]

"Macca" <Ma***@discussions.microsoft.com> wrote in message
news:E4**********************************@microsof t.com...
| Hi,
|
| I have a synchronous socket server which my app uses to read data from
| clients.
|
| To test this I have a simulated client that sends 100 byte packets.
|
| I have set up the socket server so that its buffer is bigger than this.
| I did this expecting the data to be read in one pass.
|
| However what I find is that on the first pass it only reads the first 4
| bytes and then on the second pass of begin.receive, reads the rest of the
| message. Is this usual?
|
| This happens each time I send my packet from the
| The code I have been using is the MSDN example( shown below).
|
| Can anyone tell me if it is possible to read the whole message sent form
the
| client on the first pass rather than it taking 2 or more passes?
|
| Thanks
| Macca
|
|
| using System;
| using System.Net;
| using System.Net.Sockets;
| using System.Text;
| using System.Threading;
|
| // State object for reading client data asynchronously
| public class StateObject {
| // Client socket.
| public Socket workSocket = null;
| // Size of receive buffer.
| public const int BufferSize = 100;
| // Receive buffer.
| public byte[] buffer = new byte[BufferSize];
| // Received data string.
| public StringBuilder sb = new StringBuilder();
| }
|
| public class AsynchronousSocketListener {
| // Thread signal.
| public static ManualResetEvent allDone = new ManualResetEvent(false);
|
| public AsynchronousSocketListener() {
| }
|
| public static void StartListening() {
| // Data buffer for incoming data.
| byte[] bytes = new Byte[1024];
|
| // Establish the local endpoint for the socket.
| // The DNS name of the computer
| // running the listener is "host.contoso.com".
| SN.IPHostEntry ipHostInfo = SN.Dns.GetHostEntry(hostname);
| SN.IPAddress ipAddress = ipHostInfo.AddressList[0];
| SN.IPEndPoint localEndPoint = new SN.IPEndPoint(ipAddress,
7777);
|
| // Create a TCP/IP socket.
| Socket listener = new Socket(AddressFamily.InterNetwork,
| SocketType.Stream, ProtocolType.Tcp );
|
| // Bind the socket to the local endpoint and listen for incoming
| connections.
| try {
| listener.Bind(localEndPoint);
| listener.Listen(100);
|
| while (true) {
| // Set the event to nonsignaled state.
| allDone.Reset();
|
| // Start an asynchronous socket to listen for connections.
| Console.WriteLine("Waiting for a connection...");
| listener.BeginAccept(
| new AsyncCallback(AcceptCallback),
| listener );
|
| // Wait until a connection is made before continuing.
| allDone.WaitOne();
| }
|
| } catch (Exception e) {
| Console.WriteLine(e.ToString());
| }
|
| Console.WriteLine("\nPress ENTER to continue...");
| Console.Read();
|
| }
|
| public static void AcceptCallback(IAsyncResult ar) {
| // Signal the main thread to continue.
| allDone.Set();
|
| // Get the socket that handles the client request.
| Socket listener = (Socket) ar.AsyncState;
| Socket handler = listener.EndAccept(ar);
|
| // Create the state object.
| StateObject state = new StateObject();
| state.workSocket = handler;
| handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
| new AsyncCallback(ReadCallback), state);
| }
|
| public static void ReadCallback(IAsyncResult ar) {
| String content = String.Empty;
|
| // Retrieve the state object and the handler socket
| // from the asynchronous state object.
| StateObject state = (StateObject) ar.AsyncState;
| Socket handler = state.workSocket;
|
| // Read data from the client socket.
| int bytesRead = handler.EndReceive(ar);
|
| if (bytesRead > 0) {
| // There might be more data, so store the data received so
far.
| state.sb.Append(Encoding.ASCII.GetString(
| state.buffer,0,bytesRead));
|
| // Check for end-of-file tag. If it is not there, read
| // more data.
| content = state.sb.ToString();
| if (content.IndexOf("<EOF>") > -1) {
| // All the data has been read from the
| // client. Display it on the console.
| Console.WriteLine("Read {0} bytes from socket. \n Data :
{1}",
| content.Length, content );
| // Echo the data back to the client.
| Send(handler, content);
| } else {
| // Not all data received. Get more.
| handler.BeginReceive(state.buffer, 0,
| StateObject.BufferSize, 0,
| new AsyncCallback(ReadCallback), state);
| }
| }
| }
|
| private static void Send(Socket handler, String data) {
| // Convert the string data to byte data using ASCII encoding.
| byte[] byteData = Encoding.ASCII.GetBytes(data);
|
| // Begin sending the data to the remote device.
| handler.BeginSend(byteData, 0, byteData.Length, 0,
| new AsyncCallback(SendCallback), handler);
| }
|
| private static void SendCallback(IAsyncResult ar) {
| try {
| // Retrieve the socket from the state object.
| Socket handler = (Socket) ar.AsyncState;
|
| // Complete sending the data to the remote device.
| int bytesSent = handler.EndSend(ar);
| Console.WriteLine("Sent {0} bytes to client.", bytesSent);
|
| handler.Shutdown(SocketShutdown.Both);
| handler.Close();
|
| } catch (Exception e) {
| Console.WriteLine(e.ToString());
| }
| }
|
Feb 16 '06 #4
Sebastian,

I'd appreciate it, if you could show me the example,

Regards
Macca

Feb 17 '06 #5
Hi william,

At the moment I know the exact size of each packet. It just surprises me
that every time I send a packet the first pass always sends 4 bytes then the
second time it sends the rest.

Would there ever be an occasion when the whole packet would be received on
the first pass?

Also I am looking into the most efficient way of detecting when the full
packet has been received. The Packet does not have and end of packet
indicator. I know I could use a counter to detect how many bytes have been
received and compare against the packet size but is this the most efficient
way of doing it?

Regards
Macca

"William Stacey [MVP]" wrote:
You must always *expect you will get 1 or more bytes (or 0 if shutdown by
sender) upto max of Count bytes. That is all you can expect and you need to
design your logic always with that understanding. The sender may be sending
4 bytes (maybe a length) as one Send and then sending the data as the second
Send(). This could be because they wanted to save a buffer copy to join the
two arrays. On the other hand, that could make less efficient network
traffic if it means the first send/ack will always be only 4 bytes. So do
you pay the price in the buffer join(s) or slightly more traffic. Can't
really say as it depends on the app, net speed, etc.

--
William Stacey [MVP]

"Macca" <Ma***@discussions.microsoft.com> wrote in message
news:E4**********************************@microsof t.com...
| Hi,
|
| I have a synchronous socket server which my app uses to read data from
| clients.
|
| To test this I have a simulated client that sends 100 byte packets.
|
| I have set up the socket server so that its buffer is bigger than this.
| I did this expecting the data to be read in one pass.
|
| However what I find is that on the first pass it only reads the first 4
| bytes and then on the second pass of begin.receive, reads the rest of the
| message. Is this usual?
|
| This happens each time I send my packet from the
| The code I have been using is the MSDN example( shown below).
|
| Can anyone tell me if it is possible to read the whole message sent form
the
| client on the first pass rather than it taking 2 or more passes?
|
| Thanks
| Macca
|
|
| using System;
| using System.Net;
| using System.Net.Sockets;
| using System.Text;
| using System.Threading;
|
| // State object for reading client data asynchronously
| public class StateObject {
| // Client socket.
| public Socket workSocket = null;
| // Size of receive buffer.
| public const int BufferSize = 100;
| // Receive buffer.
| public byte[] buffer = new byte[BufferSize];
| // Received data string.
| public StringBuilder sb = new StringBuilder();
| }
|
| public class AsynchronousSocketListener {
| // Thread signal.
| public static ManualResetEvent allDone = new ManualResetEvent(false);
|
| public AsynchronousSocketListener() {
| }
|
| public static void StartListening() {
| // Data buffer for incoming data.
| byte[] bytes = new Byte[1024];
|
| // Establish the local endpoint for the socket.
| // The DNS name of the computer
| // running the listener is "host.contoso.com".
| SN.IPHostEntry ipHostInfo = SN.Dns.GetHostEntry(hostname);
| SN.IPAddress ipAddress = ipHostInfo.AddressList[0];
| SN.IPEndPoint localEndPoint = new SN.IPEndPoint(ipAddress,
7777);
|
| // Create a TCP/IP socket.
| Socket listener = new Socket(AddressFamily.InterNetwork,
| SocketType.Stream, ProtocolType.Tcp );
|
| // Bind the socket to the local endpoint and listen for incoming
| connections.
| try {
| listener.Bind(localEndPoint);
| listener.Listen(100);
|
| while (true) {
| // Set the event to nonsignaled state.
| allDone.Reset();
|
| // Start an asynchronous socket to listen for connections.
| Console.WriteLine("Waiting for a connection...");
| listener.BeginAccept(
| new AsyncCallback(AcceptCallback),
| listener );
|
| // Wait until a connection is made before continuing.
| allDone.WaitOne();
| }
|
| } catch (Exception e) {
| Console.WriteLine(e.ToString());
| }
|
| Console.WriteLine("\nPress ENTER to continue...");
| Console.Read();
|
| }
|
| public static void AcceptCallback(IAsyncResult ar) {
| // Signal the main thread to continue.
| allDone.Set();
|
| // Get the socket that handles the client request.
| Socket listener = (Socket) ar.AsyncState;
| Socket handler = listener.EndAccept(ar);
|
| // Create the state object.
| StateObject state = new StateObject();
| state.workSocket = handler;
| handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
| new AsyncCallback(ReadCallback), state);
| }
|
| public static void ReadCallback(IAsyncResult ar) {
| String content = String.Empty;
|
| // Retrieve the state object and the handler socket
| // from the asynchronous state object.
| StateObject state = (StateObject) ar.AsyncState;
| Socket handler = state.workSocket;
|
| // Read data from the client socket.
| int bytesRead = handler.EndReceive(ar);
|
| if (bytesRead > 0) {
| // There might be more data, so store the data received so
far.
| state.sb.Append(Encoding.ASCII.GetString(
| state.buffer,0,bytesRead));
|
| // Check for end-of-file tag. If it is not there, read
| // more data.
| content = state.sb.ToString();
| if (content.IndexOf("<EOF>") > -1) {
| // All the data has been read from the
| // client. Display it on the console.
| Console.WriteLine("Read {0} bytes from socket. \n Data :
{1}",
| content.Length, content );
| // Echo the data back to the client.
| Send(handler, content);
| } else {
| // Not all data received. Get more.
| handler.BeginReceive(state.buffer, 0,
| StateObject.BufferSize, 0,
| new AsyncCallback(ReadCallback), state);
| }
| }
| }
|
| private static void Send(Socket handler, String data) {
| // Convert the string data to byte data using ASCII encoding.
| byte[] byteData = Encoding.ASCII.GetBytes(data);
|
| // Begin sending the data to the remote device.
| handler.BeginSend(byteData, 0, byteData.Length, 0,
| new AsyncCallback(SendCallback), handler);
| }
|
| private static void SendCallback(IAsyncResult ar) {
| try {
| // Retrieve the socket from the state object.
| Socket handler = (Socket) ar.AsyncState;
|
| // Complete sending the data to the remote device.
| int bytesSent = handler.EndSend(ar);
| Console.WriteLine("Sent {0} bytes to client.", bytesSent);
|
| handler.Shutdown(SocketShutdown.Both);
| handler.Close();
|
| } catch (Exception e) {
| Console.WriteLine(e.ToString());
| }
| }
|

Feb 17 '06 #6
| At the moment I know the exact size of each packet. It just surprises me
| that every time I send a packet the first pass always sends 4 bytes then
the
| second time it sends the rest.

How is the send side sending the bytes? Is it using two sends or one?

| Also I am looking into the most efficient way of detecting when the full
| packet has been received. The Packet does not have and end of packet
| indicator. I know I could use a counter to detect how many bytes have been
| received and compare against the packet size but is this the most
efficient
| way of doing it?

Yes. Read till X bytes received. That is the best way to do it and is very
common and well known pattern for network streams.
Here is a general pattern you can use on receives to receive byte[numBytes]
or Null if socket closed by client.

private byte[] FillBuffer(int numBytes)
{
int totRead = 0;
int read = 0;

if (numBytes == 1)
{
read = this.innerStream.ReadByte();
if (read == -1)
return null;
return new byte[] { (byte)read };
}
else
{
byte[] buff = new byte[numBytes];
do
{
read = this.innerStream.Read(buff, totRead, numBytes -
totRead);
if (read == 0)
return null;
totRead += read;
}
while (totRead < numBytes);
return buff;
}
}
--
William Stacey [MVP]

Feb 17 '06 #7
Hi William,

The send side is only using one send to send the data, however it is doing
serially to a third party device that then sends the data on to the "server"
pc over TCP sockets. I'm not sure wehter it is something to do with the
socket server or perhaps something to do with the third party device that
converts serial data to tcp socket data.

Any thoughts?

Thanks
Macca

"William Stacey [MVP]" wrote:
| At the moment I know the exact size of each packet. It just surprises me
| that every time I send a packet the first pass always sends 4 bytes then
the
| second time it sends the rest.

How is the send side sending the bytes? Is it using two sends or one?

| Also I am looking into the most efficient way of detecting when the full
| packet has been received. The Packet does not have and end of packet
| indicator. I know I could use a counter to detect how many bytes have been
| received and compare against the packet size but is this the most
efficient
| way of doing it?

Yes. Read till X bytes received. That is the best way to do it and is very
common and well known pattern for network streams.
Here is a general pattern you can use on receives to receive byte[numBytes]
or Null if socket closed by client.

private byte[] FillBuffer(int numBytes)
{
int totRead = 0;
int read = 0;

if (numBytes == 1)
{
read = this.innerStream.ReadByte();
if (read == -1)
return null;
return new byte[] { (byte)read };
}
else
{
byte[] buff = new byte[numBytes];
do
{
read = this.innerStream.Read(buff, totRead, numBytes -
totRead);
if (read == 0)
return null;
totRead += read;
}
while (totRead < numBytes);
return buff;
}
}
--
William Stacey [MVP]

Feb 17 '06 #8
No ideas. I would only say it does not really matter as long as you know
the len and can get len bytes. Even if the sender does do one send, you can
not (and should not) ever expect you will get the whole message in one read.
It is just the way it works with sockets.

--
William Stacey [MVP]

"Macca" <Ma***@discussions.microsoft.com> wrote in message
news:49**********************************@microsof t.com...
| Hi William,
|
| The send side is only using one send to send the data, however it is doing
| serially to a third party device that then sends the data on to the
"server"
| pc over TCP sockets. I'm not sure wehter it is something to do with the
| socket server or perhaps something to do with the third party device that
| converts serial data to tcp socket data.
|
| Any thoughts?
|
| Thanks
| Macca
|
| "William Stacey [MVP]" wrote:
|
| > | At the moment I know the exact size of each packet. It just surprises
me
| > | that every time I send a packet the first pass always sends 4 bytes
then
| > the
| > | second time it sends the rest.
| >
| > How is the send side sending the bytes? Is it using two sends or one?
| >
| > | Also I am looking into the most efficient way of detecting when the
full
| > | packet has been received. The Packet does not have and end of packet
| > | indicator. I know I could use a counter to detect how many bytes have
been
| > | received and compare against the packet size but is this the most
| > efficient
| > | way of doing it?
| >
| > Yes. Read till X bytes received. That is the best way to do it and is
very
| > common and well known pattern for network streams.
| > Here is a general pattern you can use on receives to receive
byte[numBytes]
| > or Null if socket closed by client.
| >
| > private byte[] FillBuffer(int numBytes)
| > {
| > int totRead = 0;
| > int read = 0;
| >
| > if (numBytes == 1)
| > {
| > read = this.innerStream.ReadByte();
| > if (read == -1)
| > return null;
| > return new byte[] { (byte)read };
| > }
| > else
| > {
| > byte[] buff = new byte[numBytes];
| > do
| > {
| > read = this.innerStream.Read(buff, totRead,
numBytes -
| > totRead);
| > if (read == 0)
| > return null;
| > totRead += read;
| > }
| > while (totRead < numBytes);
| > return buff;
| > }
| > }
| >
| >
| > --
| > William Stacey [MVP]
| >
| >
| >
| >
Feb 18 '06 #9
William,

Is it possible for me to incorporate this FillBuffer() method into an
ansynchronous socket methodology.

I have a read callback method that is called when any data is detected at
the connected socket as shown below in code I got form MSDN :-

Regards
Macca

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

// State object for reading client data asynchronously
public class StateObject {
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}

public class AsynchronousSocketListener {
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);

public AsynchronousSocketListener() {
}

public static void StartListening() {
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];

// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );

// Bind the socket to the local endpoint and listen for incoming
connections.
try {
listener.Bind(localEndPoint);
listener.Listen(100);

while (true) {
// Set the event to nonsignaled state.
allDone.Reset();

// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener );

// Wait until a connection is made before continuing.
allDone.WaitOne();
}

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

Console.WriteLine("\nPress ENTER to continue...");
Console.Read();

}

public static void AcceptCallback(IAsyncResult ar) {
// Signal the main thread to continue.
allDone.Set();

// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);

// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}

public static void ReadCallback(IAsyncResult ar) {
String content = String.Empty;

// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;

// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);

if (bytesRead > 0) {
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));

// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1) {
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content );
// Echo the data back to the client.
Send(handler, content);
} else {
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0,
StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}

private static void Send(Socket handler, String data) {
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);

// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}

private static void SendCallback(IAsyncResult ar) {
try {
// Retrieve the socket from the state object.
Socket handler = (Socket) ar.AsyncState;

// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);

handler.Shutdown(SocketShutdown.Both);
handler.Close();

} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args) {
StartListening();
return 0;
}
}

"William Stacey [MVP]" wrote:
| At the moment I know the exact size of each packet. It just surprises me
| that every time I send a packet the first pass always sends 4 bytes then
the
| second time it sends the rest.

How is the send side sending the bytes? Is it using two sends or one?

| Also I am looking into the most efficient way of detecting when the full
| packet has been received. The Packet does not have and end of packet
| indicator. I know I could use a counter to detect how many bytes have been
| received and compare against the packet size but is this the most
efficient
| way of doing it?

Yes. Read till X bytes received. That is the best way to do it and is very
common and well known pattern for network streams.
Here is a general pattern you can use on receives to receive byte[numBytes]
or Null if socket closed by client.

private byte[] FillBuffer(int numBytes)
{
int totRead = 0;
int read = 0;

if (numBytes == 1)
{
read = this.innerStream.ReadByte();
if (read == -1)
return null;
return new byte[] { (byte)read };
}
else
{
byte[] buff = new byte[numBytes];
do
{
read = this.innerStream.Read(buff, totRead, numBytes -
totRead);
if (read == 0)
return null;
totRead += read;
}
while (totRead < numBytes);
return buff;
}
}
--
William Stacey [MVP]

Feb 20 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: javastudent | last post by:
Hi, I am implementing a server that reads for socket connections at a port, and processes the socket on a separate thread. We do not control the client implementation. Here is the scenario. ...
4
by: yaron | last post by:
Hi, I have a problem when sending data over TCP socket from c# client to java server. the connection established ok, but i can't send data from c# client to java server. it's work ok with...
7
by: Nuno Magalhaes | last post by:
I've got a problem which relates to reading HTTP data. I've got the socket connected to a web site and then I send "GET / HTTP/1.1\n\n" and the page is received after a while but not all of the...
5
by: Dave A | last post by:
I have an application that does lots of socket communications all asynchronously via the TcpClient class. The code has been working 99.9999% of the time (yeah one of those bugs) but occasionally...
8
by: AndrewTK | last post by:
Hello, I'm trying to read data from a socket and I'm not seeing what I'm expecting.... it seems to skip the first line of data. I am new to Python and just trying to test what I can do with...
4
by: Patrick Altman | last post by:
I am attempting to use a HEAD request against Amazon S3 to check whether a file exists or not and if it does parse the md5 hash from the ETag in the response to verify the contents of the file so...
1
by: Diego F. | last post by:
Hello. I'm having problems reading data from a socket. In my test, I see the maximum size to get data from the socket is 8192 bytes. In my tests, if I send less that 8192, the readen data have...
1
by: starter08 | last post by:
Hi, I have a C++ routine(client-side) which uploads an xml file to a web server by making a socket connection and sending all the post request through that socket. On the server side I have a cgi...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.