i've got the following problem in a client socket (sync) / server socket (async) environment.
If I send multiple messages from the client to the server, the first one finishs without any problems and will be received by the client without issues. When I send the 2nd message, just a few bytes go through. It doesn't seem to be a client problem, because it looks the client sends the whole message all the time. The crazy thing is, if I completely stop the project on the client and start again the first message completes again, also if the server component runs through all the time.
What I want to do...
Basically, I want to transfer different objects, most xml structured through the network and receive it on the client. Therefore, I do the Serialization/Deserialization.
The basics of the following code are extended msdn examples.
//CLIENT:
class ProgramClient
{
static void Main(string[] args)
{
string rootNode = "config";
StreamReader configStream = new StreamReader(config);
XmlDocument xml = new XmlDocument();
xml.Load(configStream);
SynchronousSocketClient socket = new SynchronousSocketClient("192.168.0.1", 40001, "c:\\log", xml);
socket.StartClient();
socket.Dispose();
socket = new SynchronousSocketClient("192.168.0.1", 40001, "c:\\log", xml);
socket.StartClient();
socket.Dispose();
}
}
class SynchronousSocketClient : IDisposable
{
private string ip;
private int port;
private object data;
public StreamWriter log;
public event EventHandler Disposed;
public SynchronousSocketClient(string ip, int port, string logfile, object data)
{
this.ip = ip;
this.port = port;
this.data = data;
openLog(logfile);
}
public void openLog(string logfile)
{
log = new StreamWriter(logfile, true);
}
public void Dispose()
{
log.Close();
if (this.Disposed != null)
this.Disposed(this, EventArgs.Empty);
}
// Convert an object to a byte array
private byte[] Serialize(object obj)
{
Stream stream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, obj);
byte[] b = null;
b = new byte[stream.Length];
stream.Position = 0;
stream.Read(b, 0, (int)stream.Length);
stream.Close();
return b;
}
public void StartClient()
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try {
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.GetHostEntry(ip);
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress,port);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Connect the socket to the remote endpoint. Catch any errors.
try {
sender.Connect(remoteEP);
log.WriteLine(DateTime.Now+": Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
byte[] msg = Serialize(data);
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
log.WriteLine(DateTime.Now + ": {0}",
Encoding.Unicode.GetString(bytes,0,bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
} catch (ArgumentNullException ane) {
log.WriteLine(DateTime.Now + ": ArgumentNullException : {0}", ane.ToString());
} catch (SocketException se) {
log.WriteLine(DateTime.Now + ": SocketException : {0}", se.ToString());
} catch (Exception e) {
log.WriteLine(DateTime.Now + ": Unexpected exception : {0}", e.ToString());
}
} catch (Exception e) {
log.WriteLine(DateTime.Now+": "+e.ToString());
}
}
}
//SERVER:
class ProgramServer
{
static void Main(string[] args)
{
NetworkSocket socket = new NetworkSocket(nwsocketport);
socket.Start();
}
}
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of send buffer.
public const int sBufferSize = 1024;
// send buffer.
public byte[] sBuffer = new byte[sBufferSize];
// Received data object;
public object data = null;
// bytes read so far
public int bytesRead;
//receive buffer
public byte[] rBuffer;
}
public class NetworkSocket
{
private int port;
Socket listener;
IPEndPoint localEndPoint;
public NetworkSocket(int port) {
this.port = port;
}
public void Start() {
// Establish the local endpoint for the socket.
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[1];
localEndPoint = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
//set socket timeouts
listener.SendTimeout = 5000;
listener.ReceiveTimeout = 5000;
// Bind the socket to the local endpoint and listen for incoming connections.
try {
listener.Bind(localEndPoint);
listener.Listen(1);
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
public 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();
// Data buffer for incoming data.
state.rBuffer = new Byte[listener.ReceiveBufferSize];
state.workSocket = handler;
handler.BeginReceive(state.rBuffer, 0, state.rBuffer.Length, 0,
new AsyncCallback(ReadCallback), state);
try
{
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void ReadCallback(IAsyncResult ar) {
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;
//handler.ReceiveTimeout = 2000;
// Read data from the client socket.
state.bytesRead = handler.EndReceive(ar);
Send(handler, "paket successfully tranferred");
state.data = Deserialize(state.rBuffer);
bool xmlDoc = true;
try
{
XDocument.Parse(state.data.ToString());
}
catch
{
xmlDoc = false;
}
if (xmlDoc)
XMLHandler.update(state.data.ToString());
}
private void Send(Socket handler, String data) {
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.Unicode.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private 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());
}
}
// Convert a byte array to an Object
private object Deserialize(byte[] b)
{
MemoryStream stream = new MemoryStream(b);
BinaryFormatter bf = new BinaryFormatter();
object obj = bf.Deserialize(stream);
stream.Close();
return obj;
}
// convert object to byte array
private byte[] Serialize(object obj)
{
Stream stream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, obj);
byte[] b = null;
b = new byte[stream.Length];
stream.Position = 0;
stream.Read(b, 0, (int)stream.Length);
stream.Close();
return b;
}
}
Could anybody please help me with my problem? I am not experienced in Socket Programming...
In your ReadCallback you need to start another BeginReceive, just like how you call BeginAccept in the AcceptCallback method.
A more serious issue with your code is that you expect to receive one entire message per ReadCallback. In reality, you could receive half a message, one byte, or three messages.
Related
I have a code that sends some commands to the server by using Async messaging. But unfortunately I am unable to receive the data as a string. I mean in the console I get the message that I got a response from the server of 150 bytes. but what I need is to get the data itself in the console. Tried almost everything but was not successful. the code is below :
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
// State object for receiving data from remote device.
public class StateObject
{
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
// Client socket.
public Socket workSocket;
}
public class AsynchronousClient
{
// The port number for the remote device.
private const int port = 5002;
// ManualResetEvent instances signal completion.
private static readonly ManualResetEvent connectDone =
new ManualResetEvent(false);
private static readonly ManualResetEvent sendDone =
new ManualResetEvent(false);
private static readonly ManualResetEvent receiveDone =
new ManualResetEvent(false);
// The response from the remote device.
private static string response = string.Empty;
public static void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// The name of the
// remote device is "host.contoso.com".
var ipAddress = IPAddress.Parse("localhost");
var remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
var client = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
ConnectCallback, client);
connectDone.WaitOne();
var data =
"<XCOM sid=\"A813833FF8E8EF0122B8313265538126\"> <XREQ name=\"NOP\"/> </XCOM>";
data += '\0';
// Send test data to the remote device.
Send(client, data);
sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
// Write the response to the console.
Console.WriteLine("Response received : {0}", response);
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
var client = (Socket) ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint);
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
var state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
ReceiveCallback, state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
Console.WriteLine("Receieve Call Back Invoked");
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
Console.WriteLine("Receieve End Receieve");
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));
Console.WriteLine("Read : " + bytesRead.ToString());
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
Console.WriteLine("Begin Receieve completed");
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
Console.WriteLine("Received data from client");
// Signal that all bytes have been received.
receiveDone.Set();
}
Console.WriteLine("completed receive callback");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, string data)
{
// Convert the string data to byte data using ASCII encoding.
var byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0,
SendCallback, client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
var client = (Socket) ar.AsyncState;
// Complete sending the data to the remote device.
var bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
I just copied the code from msdn examples, asynchronous server and client socket program. But I am getting error System.Net.SocketsException: No connection could be made because the target machine actively refused it 127.0.0.1:11000
Client Program :
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
// State object for receiving data from remote device.
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousClient
{
// The port number for the remote device.
private const int port = 11000;
// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
private static ManualResetEvent sendDone =
new ManualResetEvent(false);
private static ManualResetEvent receiveDone =
new ManualResetEvent(false);
// The response from the remote device.
private static String response = String.Empty;
private static void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// The name of the
// remote device is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.Resolve("localhost");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// Send test data to the remote device.
Send(client, "This is a test<EOF>");
sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
// Write the response to the console.
Console.WriteLine("Response received : {0}", response);
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.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));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, 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.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args)
{
StartClient();
return 0;
}
}
Server Program :
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;
}
}
change
IPAddress ipAddress = ipHostInfo.AddressList[0];
to
IPAddress ipAddress = IPAddress.Any;
in StartListening method....
`
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
namespace ServerSocket
{
class Class1
{
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 = IPAddress.Parse("192.168.1.89");
//IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 8095);
// 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.
MessageBox.Show("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
//TcpListener tcpListener = new TcpListener(ipAddress, 8095);
//tcpListener.Start();
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
MessageBox.Show("\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.
MessageBox.Show(string.Concat("Read bytes from socket. \n Data :",
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);
MessageBox.Show(string.Concat("Sent bytes to client.", bytesSent));
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
//public static int Main(String[] args)
//{
// StartListening();
// return 0;
//}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Windows.Forms;
namespace ClientSocket
{
class Class1
{
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousClient
{
// The port number for the remote device.
public const int port = 8095;
// ManualResetEvent instances signal completion.
//set the initial state to signaled
public static ManualResetEvent connectDone =
new ManualResetEvent(false);
public static ManualResetEvent sendDone =
new ManualResetEvent(false);
public static ManualResetEvent receiveDone =
new ManualResetEvent(false);
// The response from the remote device.
public static String response = String.Empty;
public static void StartClient(string Msg)
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// The name of the
// remote device is "host.contoso.com".
//IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPAddress ipAddress = IPAddress.Parse("192.168.1.89");
//IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");
//IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
//TcpListener tcpListener = new TcpListener(ipAddress, port);
//tcpListener.Start();
connectDone.WaitOne();//Blocks the current thread until the current System.Threading.WaitHandle receives a signal.
// Send test data to the remote device.
Send(client, Msg + "<EOF>");
sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
// Write the response to the console.
MessageBox.Show("Response received", response);
// Release the socket.
//client.Shutdown(SocketShutdown.Both);
//client.Close();
// client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
}
catch (SocketException e)
{
MessageBox.Show(e.Message);
}
}
public static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;//Gets a user-defined object that qualifies or contains information about an
//asynchronous operation.
// Complete the connection.
client.EndConnect(ar);//Ends a pending asynchronous connection request.
MessageBox.Show(string.Concat("Socket connected to ",
client.RemoteEndPoint.ToString()));
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public static void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
MessageBox.Show("Receivecallback");
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.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));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public static void Send(Socket client, 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.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
}
public static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
MessageBox.Show(string.Concat("Sent bytes to server.", bytesSent.ToString()));
SocketConnected(client);
// Signal that all bytes have been sent.
sendDone.Set();
MessageBox.Show("Send Callback");
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
public static bool SocketConnected(Socket s)
{
bool part1 = s.Poll(1000, SelectMode.SelectRead);
bool part2 = (s.Available == 0);
if (part1 && part2)
return false;
else
return true;
}
//public static int Main(String[] args)
//{
// StartClient();
// return 0;
//}
}
}
}
`
I have tried the Asynchronous Client and Server Communication Pattern with a C# windows Application.
I have tested the Server application from different system and the Client Application on my own system.
Once I run both application same time I can receive the Message. After that I have to restart both application to send another message. But I need it can be send data for all time with out any restarting application.
One aspect that I see is that the server shuts down the socket connection after sending data to client. This means that the client needs to initiate another round of connect sequence to data exchange ( what you mention as restarting the application). Have the server to retain connection (don't close) on exchanging data.
handler.Shutdown(SocketShutdown.Both);
handler.Close();
I'm trying to serialize a MessageData class and send it by network.
This class contain picture in bitmap that I need to display on a form.
The transmitted bitmap it's a frame that a webcam need to transmit several times each second by network to a WinForm.
This program it's a test and in future will be splitted in two parts, client part with receiver method and winform, and a server part with webcam and sender method.
Actually the Serializing and sending-receiving of the object-picture is not working, the winform is not showing any image if I force picture to pass from the serializing-network process instad of get it directly.
The webcam frames are managed with the Emgu.CV library, and locally it's working very well, but not by remote with the serialization sending of the frames.
All that follow is inside the namespace Idea:
[Serializable]
public class MessageData {
public MessageData(Bitmap img){
Picture = img;
}
public static Bitmap Picture { get; set; }
}
[Serializable]
public class MessageSendData {
public MessageSendData(Bitmap img){
Picture = img;
}
public static Bitmap Picture { get; set; }
}
public partial class Idea : Form
{
//declaring global variables
private Capture capture; //takes images from camera as image frames
private bool captureInProgress; // checks if capture is executing
private TcpListener ascolto;
Bitmap bitmapricevuto;
public Idea()
{
InitializeComponent();
}
private void Idea_Load(object sender, EventArgs e)
{
}
private void ProcessFrame(object sender, EventArgs arg)
{
Image<Bgr, Byte> ImageFrame = capture.QueryFrame(); //line 1
// CamImageBox.Image = byteArrayToImage(MyImageBytes(ImageFrame.ToBitmap()));
// CamImageBox.Image = ImageFrame.ToBitmap();
Thread r = new Thread(Ricevi);
r.Start();
MessageSendData.Picture = ImageFrame.ToBitmap();
Thread s = new Thread(Spedisci);
s.Start();
lock (MessageData.Picture){
CamImageBox.Image = MessageData.Picture;
}
}
private void btnStart_Click(object sender, EventArgs e)
{
#region if capture is not created, create it now
if (capture == null)
{
try
{
capture = new Capture();
}
catch (NullReferenceException excpt)
{
MessageBox.Show(excpt.Message);
}
}
#endregion
if (capture != null)
{
if (captureInProgress)
{ //if camera is getting frames then stop the capture and set button Text
// "Start" for resuming capture
btnStart.Text = "Start!"; //
Application.Idle -= ProcessFrame;
}
else
{
//if camera is NOT getting frames then start the capture and set button
// Text to "Stop" for pausing capture
btnStart.Text = "Stop";
Application.Idle += ProcessFrame;
}
captureInProgress = !captureInProgress;
}
}
private void ReleaseData()
{
if (capture != null)
capture.Dispose();
}
public static void Ricevi()
{
IPAddress address = IPAddress.Parse("127.0.0.1");
TcpListener listener = new TcpListener(address, 8585);
listener.Start();
Bitmap mia;
try
{
using (TcpClient client = listener.AcceptTcpClient())
{
NetworkStream stream = client.GetStream();
IFormatter formatter = new BinaryFormatter();
while (true)
{
lock (MessageData.Picture){
MessageData.Picture = (Bitmap)formatter.Deserialize(stream);
}
}
}
}
catch(Exception ex) { }
return;
}
public static void Spedisci()
{
IPAddress address = IPAddress.Parse("127.0.0.1");
TcpClient client = new TcpClient();
try
{
client.Connect(address, 8585);
// Retrieve the network stream.
NetworkStream stream = client.GetStream();
IFormatter formatter = new BinaryFormatter();
while(true)
{
lock (MessageSendData.Picture) {
formatter.Serialize(stream, MessageSendData.Picture);
//Thread.Sleep(1000);
}
}
}
catch (Exception ex) { }
}
/*
public byte[] MyImageBytes(Image MyImage)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(MyImage, typeof(byte[]));
}
public Image byteArrayToImage(byte[] bytesArr)
{
MemoryStream memstr = new MemoryStream(bytesArr);
Image img = Image.FromStream(memstr);
return img;
}
*/
}
}
'
I've realized two methods: 1-First method convert the bitmap in a byte array. 2-Second method convert the byte array in a bitmap. Testing them directly without send the converted bytes by tcp network I see that all software are working. Now I've created two methods "Invia" and "Ricevi" that are sending and receiving with async methods the bytearrays by spliting them in stream of a length of 1024 each. My issue on compiling it's about the Async Task methods returned types. How to fix this threads Task async issues?
'
private void ProcessFrame(object sender, EventArgs arg)
{
Image<Bgr, Byte> ImageFrame = capture.QueryFrame();
invia(MyImageBytes(ImageFrame.ToBitmap()));
CamImageBox.Image = ricevi();
}
public byte[] MyImageBytes(Image MyImage)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(MyImage, typeof(byte[]));
}
'
Send (Invia) and Receive(Ricevi) methods last version here showed below are using the chars converted to bytes array and appended to the bitmap bytes array for send and receive the bitmap. Actually I've issues during compiling:
public static void invia(byte[] bytetosend)
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try {
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress,11000);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
// Connect the socket to the remote endpoint. Catch any errors.
try {
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
var mahByteArray = new ArrayList<byte>();
mahByteArray.AddRange(bytetosend);
string eof = "<EOF>";
mahByteArray.Insert(0, Convert.ToByte(eof)); // Adds eof bytes to the beginning.
byte[] msg = mahByteArray.ToArray();
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes,0,bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
} catch (ArgumentNullException ane) {
Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
} catch (SocketException se) {
Console.WriteLine("SocketException : {0}",se.ToString());
} catch (Exception e) {
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
} catch (Exception e) {
Console.WriteLine( e.ToString());
}
}
public static void ricevi()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
var scambioArray = new ArrayList();
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
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(10);
// Start listening for connections.
while (true)
{
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
string eofr = "<EOF>";
byte[] trova = Convert.ToByte(eofr);
// An incoming connection needs to be processed.
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
if (bytes.IndexOf(trova))
{
var mahByteArray = new ArrayList();
mahByteArray.AddRange(bytes);
mahByteArray.Remove(trova);
bytes = mahByteArray.ToArray();
break;
}
scambioArray.AddRange(bytes);
}
// Echo the data back to the client.
byte[] msg = scambioArray.ToArray();
MessageData.Picture = byteArrayToImage(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Try something like this
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static void invia(byte[] bytetosend)
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
var mahByteArray = new List<byte>();
mahByteArray.AddRange(bytetosend);
string eof = "<EOF>";
mahByteArray.Insert(0, Convert.ToByte(eof)); // Adds eof bytes to the beginning.
byte[] msg = mahByteArray.ToArray();
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void ricevi()
{
// Data buffer for incoming data.
List<byte> bytes = (new Byte[1024]).ToList();
List<byte> scambioArray = new List<byte>();
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
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(10);
// Start listening for connections.
while (true)
{
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
string eofr = "<EOF>";
List<byte> trova = Encoding.UTF8.GetBytes(eofr).ToList();
// An incoming connection needs to be processed.
while (true)
{
bytes = (new byte[1024]).ToList();
int bytesRec = handler.Receive(bytes.ToArray());
if (bytes.Contains(trova[0]))
{
List<byte> mahByteArray = new List<byte>();
mahByteArray.AddRange(bytes);
mahByteArray.Remove(trova[0]);
bytes = mahByteArray.ToArray().ToList();
break;
}
scambioArray.AddRange(bytes);
}
// Echo the data back to the client.
byte[] msg = scambioArray.ToArray();
MemoryStream stream = new MemoryStream(msg);
MessageData.Image = Image.FromStream(stream);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
first post ever on stack overflow!
Anyway...I'm trying to teach myself networking programming in my spare time and I've reached a snag I just cant wrap my head around. After playing with synchronous networking methodology over a few days I decided to make a client/server program that could:
Handle multiple concurrent connections
Handle multiple streams of communication
Have true two way communication
On a more general level I want to make a chat program. Multiple client connections to a server that can send and receive data individually with no problems...but also have the server send data from each client to the others.
Now I haven't gotten as far as I'd like to yet so I'm here for a little guidance. I can't seem to get my loops working properly and I'm sure it has to do with the asynchronous nature of the code...for whatever reason I just can't seem to figure out whats wrong. Here's the the blocks of code:
Server.cs
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];
IPAddress ipAddress = System.Net.IPAddress.Loopback;
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 3000);
// 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;
}
}
Client.cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class Program
{
public static ManualResetEvent connectDone = new ManualResetEvent(false);
public static ManualResetEvent sendDone = new ManualResetEvent(false);
public static ManualResetEvent receiveDone = new ManualResetEvent(false);
public static void Connect(EndPoint remoteEP, Socket client)
{
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, 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.
client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.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));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
string response = state.sb.ToString();
Console.WriteLine(response);
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
static void Main(string[] args)
{
IPAddress ipAddress = System.Net.IPAddress.Loopback;
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 3000);
Socket sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
Connect(localEndPoint, sock);
string packet;
while (true)
{
packet = Console.ReadLine();
packet += "<EOF>";
Send(sock, packet);
Receive(sock);
connectDone.WaitOne();
}
}
}
You don't need any loops or waithandles when you go asynchronous. Just fire away another beginAccept inside AcceptCallback and you server will start listening again after accepting a client.
If your problem is that the server responses only once and then shuts down, then, well, that is what you say it to do in a SendCallback - it sends stuff and then shuts down. Call handler.beginReceive instead of handler.shutdown (you'll have to carry your StateObject all the way down to this callback, not just handler).