473,320 Members | 1,572 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 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 3565
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...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.