Constantly running server - c#

When a client disconnects, the server closes. Tell me how to leave the ability to connect new customers after the close of the first session .Thanks in advance.
namespace tcpserver
{
class Program
{
static void Main(string[] args)
{
string cmd;
int port = 56568;
Server Serv = new Server(); // Создаем новый экземпляр класса
// сервера
Serv.Create(port);
while (true)
{
cmd = Console.ReadLine(); // Ждем фразы EXIT когда
// понадобится выйти из приложения.
// типа интерактивность.
if (cmd == "EXIT")
{
Serv.Close(); // раз выход – значит выход. Серв-нах.
return;
}
}
//while (Serv.Close() == true) { Serv.Create(port); }
}
public class Server // класс сервера.
{
private int LocalPort;
private Thread ServThread; // экземпляр потока
TcpListener Listener; // листенер))))
public void Create(int port)
{
LocalPort = port;
ServThread = new Thread(new ThreadStart(ServStart));
ServThread.Start(); // запустили поток. Стартовая функция –
// ServStart, как видно выше
}
public void Close() // Закрыть серв?
{
Listener.Stop();
ServThread.Abort();
return;
}
private void ServStart()
{
Socket ClientSock; // сокет для обмена данными.
string data;
byte[] cldata = new byte[1024]; // буфер данных
Listener = new TcpListener(LocalPort);
Listener.Start(); // начали слушать
Console.WriteLine("Waiting connections on " + Convert.ToString(LocalPort) + " port");
try
{
ClientSock = Listener.AcceptSocket(); // пробуем принять клиента
}
catch
{
ServThread.Abort(); // нет – жаль(
return;
}
int i = 0;
if (ClientSock.Connected)
{
while (true)
{
try
{
i = ClientSock.Receive(cldata); // попытка чтения
// данных
}
catch
{
}
try
{
if (i > 0)
{
data = Encoding.ASCII.GetString(cldata).Trim();
Console.WriteLine("<" + data);
if (data == "CLOSE") // если CLOSE –
// вырубимся
{
ClientSock.Send(Encoding.ASCII.GetBytes("Closing the server..."));
ClientSock.Close();
Listener.Stop();
Console.WriteLine("Server closed. Reason: client wish! Type EXIT to quit the application.");
ServThread.Abort();
return;
}
else
{ // нет – шлем данные взад.
ClientSock.Send(Encoding.ASCII.GetBytes("Your data: " + data));
}
}
}
catch
{
ClientSock.Close(); //
Listener.Stop();
Console.WriteLine("Client disconnected. Server closed.");
ServThread.Abort();
}
}
}
}
}
}
}

Typical threaded server code will read more like this (in a pseudo code, because I don't know enough Java details to write it exactly, and because C is a bit stifling):
socket s = new socket
bind s to an optional IP, port
listen s
while true
cli = accept s
t = new thread(handle_client, cli)
maybe disown thread, so no need to join it later
t.start
The important point is that creating the socket, binding it to an address, and listen are all handled outside the loop, and accept() and starting threads are inside the loop.
You may want to wrap this entire block inside another thread; that is acceptable. The important part is separating the listen from the accept and per-client thread. This allows your code to stop accepting new connections but handle existing clients until they disconnect, or disconnect existing connections when they use their allotment of resources but continue accepting connections, etc. (Note how your last catch block will terminate the server if any single client socket throws an exception; that kind of code is easy to avoid with the usual server layout.)

replace
ServThread.Abort();
return;
with a continue instead, this will not break the while loop and yet stop the current "round". Please consider reading this: http://www.codeproject.com/KB/IP/serversocket.aspx nice project to build from

Related

Can't connect with my bluetooth device

I have been working on this for days, but can't fix the problem.
This is what I've got right now ->
Bluetooth handler
protected BluetoothAdapter bluetoothAdapter;
protected BluetoothServer btServer;
protected BluetoothSocket btSocket;
protected BluetoothDevice pairedBTDevice;
protected BluetoothListener btListener;
protected ParcelUuid uuid;
public BluetoothHandler()
{
BluetoothAdapter = null;
}
public void Initialize()
{
BluetoothAdapter = BluetoothAdapter.DefaultAdapter;
// Check if it has a bluetooth interface
if (BluetoothAdapter == null)
{
Console.WriteLine("Bluetooth is not available!");
return;
}
// Check if bluetooth interface is enabled
if (!BluetoothAdapter.IsEnabled)
{
BluetoothAdapter.Enable();
}
int count = 0;
// Get all the devices in the bluetooth list
var listDevices = BluetoothAdapter.BondedDevices;
if (listDevices.Count > 0)
{
foreach (var btDevice in listDevices)
{
// Get the specific controller
if (btDevice.Name == "MOCUTE-032_B52-CA7E")
{
UUID = btDevice.GetUuids().ElementAt(count);
pairedBTDevice = btDevice;
}
count++;
}
}
// Check if bluetooth is enabled
// Check if there is a device
if (BluetoothAdapter.IsEnabled && pairedBTDevice != null)
{
// Check if it's paired
if (pairedBTDevice.BondState == Bond.Bonded)
{
// First start the server
btServer = new BluetoothServer(this);
Thread.Sleep(1000);
// Start a new thread
Thread thread = new Thread(new ThreadStart(Connect));
thread.Start();
}
}
}
protected void Connect()
{
// Check if there is no socket already
if (btSocket == null)
{
try
{
btSocket = pairedBTDevice.CreateRfcommSocketToServiceRecord(UUID.Uuid);
}
catch (IOException ex)
{
throw ex;
}
}
try
{
Console.WriteLine("Attempting to connect...");
// Create a socket connection
btSocket.Connect();
}
catch
{
Console.WriteLine("Connection failed...");
Console.WriteLine("Attempting to connect...");
try
{
btSocket = pairedBTDevice.CreateInsecureRfcommSocketToServiceRecord(UUID.Uuid);
btSocket.Connect();
}
catch
{
Console.WriteLine("Connection failed...");
return;
}
}
Console.WriteLine("Client socket is connected!");
Read();
}
protected void Read()
{
btListener = new BluetoothListener();
btListener.Read(btSocket);
}
Bluetooth server
private BluetoothHandler bluetoothHandler;
private BluetoothServerSocket serverSocket;
private Thread thread;
public BluetoothServer(BluetoothHandler bluetoothHandler)
{
this.bluetoothHandler = bluetoothHandler;
BluetoothServerSocket tmp = null;
try
{
tmp = bluetoothHandler.BluetoothAdapter.ListenUsingRfcommWithServiceRecord("MOCUTE-032_B52-CA7E", bluetoothHandler.UUID.Uuid);
}
catch (IOException ex)
{
throw ex;
}
serverSocket = tmp;
thread = new Thread(new ThreadStart(Run));
thread.Start();
}
protected void Run()
{
System.Console.WriteLine("Server is running...");
while (true)
{
try
{
serverSocket.Accept();
}
catch (IOException ex)
{
System.Console.WriteLine("FAILED! === > " + ex);
}
}
}
Bluetooth listener
protected Stream mmInStream;
public void Read(BluetoothSocket socket)
{
Stream tmpIn = null;
try
{
tmpIn = socket.InputStream;
}
catch (IOException ex)
{
throw ex;
}
mmInStream = tmpIn;
Thread thread = new Thread(new ThreadStart(Run));
thread.Start();
}
protected void Run()
{
byte[] buffer = new byte[1024];
int bytes;
Console.WriteLine("Waiting for events...");
while (true)
{
try
{
if (mmInStream.IsDataAvailable())
{
bytes = mmInStream.Read(buffer, 0, buffer.Length);
}
}
catch (Exception ex)
{
throw ex;
}
}
}
I would like to connect with the following controller ->
So, I would like to catch the buttons events from the controller, but I have no idea anymore..
I've got also the known error: Java.IO.IOException: "read failed, socket might closed or timeout, read ret: -1
The UUID of the controller is: 00001124-0000-1000-8000-00805f9b34fb
I have one example to connect to a Bluetooth(2.0) device on my Github you can check the code and see if you setup is correct here is the link https://github.com/AlejandroRuiz/Mono/blob/master/Arduino/Bluetooth/MainActivity.cs if you have any specific question about the code please let me know also you need to be sure what kind of bluetooth is using because the way to connect to a 4.0 BLE is very different that the old 2.0
The problem is solved. I didn't need a Bluetooth socket. I just used the override methods "KeyDown" and "KeyUp". It works great now :)
If you need a socket and you've got an exception like IOException: read failed, socket might closed then you should read my fix here:
IOException: read failed, socket might closed - Bluetooth on Android 4.3

TCP Socket BeginReceive stops after receiving few messages

This is my scenario:
Client :
Send xml data in pieces continuously 24/7 - (It is working fine and it is not in my control).
Server - My Code:
1. Listen continuously.
2. Receive the incoming message, buffer it and create valid xml from buffer.
3. Send it to the MSMQ ( Host will do this )
I wrote a tcp server code (adding pieces of code from google), which will be hosted in windows service. Everything works fine when I run the service in local but when I place it PROD, it listens upto 73K messages and it stops receiving. It is not throwing any exception. It just blocks at BeginReceive function. I have tried using ReceiveTimeOut also. I have seen netstat also and the connections is still in established stat.
When I restart the service, it again works fine. Here I am posting my server code. Please help on this.
StringBuilder content = new StringBuilder();
public event MessageReceiveEventHandler MessageReceived;
// An ArrayList is used to keep track of worker sockets that are designed
// to communicate with each connected client. Make it a synchronized ArrayList
// For thread safety
private System.Collections.ArrayList workerSocketList =
ArrayList.Synchronized(new System.Collections.ArrayList());
private int m_clientCount = 0;
private Socket m_mainSocket = null;
private AsyncCallback ReadCallback;
private AsyncCallback ConnectionCallback;
public MedDeviceListener(string ipAddress, int port, int maxConnections=100)
{
ProfileProvider.Instance.LogInformationIf(_debug);
this._port = port;
this._ipAddress = ipAddress;
this._maxConnections = maxConnections;
ReadCallback = new AsyncCallback(Receive_handler);
ConnectionCallback = new AsyncCallback(Connection_handler);
lenghtofStartMsg = header.Length;
lengthOfEndMsg = footer.Length;
}
public void Start()
{
ProfileProvider.Instance.LogInformationIf(_debug);
// Data buffer for incoming data.
byte[] bytes = new Byte[_bufferSize];
// Establish the local endpoint for the socket.
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(_ipAddress), _port);
// Create a TCP/IP socket.
m_mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
m_mainSocket.Bind(localEndPoint);
m_mainSocket.Listen(100);
InstrumentationProvider.Instance.LogInformation("MedDeviceListener successfully connected to IP:" + _ipAddress+"\nPort :"+_port);
m_mainSocket.BeginAccept(ConnectionCallback, m_mainSocket);
}
catch (Exception e)
{
InstrumentationProvider.Instance.LogException("MedDeviceListener.Start", e);
throw e;
}
}
private void Connection_handler(IAsyncResult ar)
{
try
{
ProfileProvider.Instance.LogInformationIf(_debug);
Socket listener = (Socket)ar.AsyncState;
Socket workerSocket = listener.EndAccept(ar);
// Now increment the client count for this client
// in a thread safe manner
Interlocked.Increment(ref m_clientCount);
// Add the workerSocket reference to our ArrayList
workerSocketList.Add(workerSocket);
SendConnectedAck(_clientConnectAckMessage, m_clientCount);
WaitForData(workerSocket, m_clientCount);
//Resume the listening callback loop
listener.BeginAccept(Connection_handler, listener);
}
catch (ObjectDisposedException)
{
InstrumentationProvider.Instance.LogInformation("The listener socket has been closed");
}
catch (Exception ex)
{
InstrumentationProvider.Instance.LogException("Connection_handler", ex);
throw;
}
}
private void Receive_handler(IAsyncResult ar)
{
ProfileProvider.Instance.LogInformationIf(_debug);
StateObject state = (StateObject)ar.AsyncState;
try
{
// Retrieve the state object and the handler socket
// from the asynchronous state object.
Socket workSocket = state.workSocket;
// Read data from the client socket.
int bytesRead = workSocket.EndReceive(ar);
if (bytesRead > 0)
{
//InstrumentationProvider.Instance.LogInformationIf(_debug, bytesRead+" read..");
// There might be more data, so parse the data received so far.
string data= Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
try
{
ParseIncomingMessage(data, workSocket);
}
catch(Exception parseEx)
{
content.Clear();
InstrumentationProvider.Instance.LogException("ParseIncomingMessage", parseEx);
}
}
WaitForData(state.workSocket, state.clientNumber);
}
catch (ObjectDisposedException)
{
InstrumentationProvider.Instance.LogInformation("Receive_handler: The listener socket has been closed");
}
catch (SocketException se)
{
//close the existing connection
CloseSockets();
//restart it again
this.Start();
}
}
private void WaitForData(Socket workerSocket, int clientNumber)
{
ProfileProvider.Instance.LogInformationIf(_debug);
try
{
StateObject theSocPkt = new StateObject(workerSocket, clientNumber);
workerSocket.ReceiveTimeout = 2000;
workerSocket.BeginReceive(theSocPkt.buffer, 0,
theSocPkt.buffer.Length,
SocketFlags.None,
Receive_handler,
theSocPkt);
}
catch(TimeoutException ex)
{
InstrumentationProvider.Instance.LogException("WaitForData - TimeOutException", ex);
}
catch (SocketException se)
{
InstrumentationProvider.Instance.LogException("MedDeviceListener.WaitForData", se);
//close the existing connection
CloseSockets();
//restart it again
this.Start();
}
catch (Exception ex)
{
InstrumentationProvider.Instance.LogException("WaitForData",ex);
//close the existing connection
CloseSockets();
//restart it again
this.Start();
}
}
private void ParseIncomingMessage(string msg,Socket wrkSocket)
{
Socket workSocket = wrkSocket;
bool hasStartTag = isMsgContainsStartTag(msg);
bool hasEndTag = isMsgContainsEndTag(msg);
int startTagIndex = indexOfStartTag(msg);
int endTagIndex = indexOfEndTag(msg);
// If the incomming message dont have either start or end tag
if (hasStartTag == false && hasEndTag == false)
{
content.Append(msg);
}
//check for the starttag first
//if message contains startTag
else if (hasStartTag)
{
if (startTagIndex != 0)//there is something before starttag
{
string subStr = msg.Substring(0, startTagIndex);
content.Append(subStr);
//Check and send the content
CheckSendMessage(workSocket);
//Parse the remaining message from start tag to end of the message
ParseIncomingMessage(msg.Substring(startTagIndex, msg.Length - subStr.Length), wrkSocket);
}
else if (startTagIndex == 0)
{
content.Clear();
if (hasEndTag)
{
int endOfEndTag = endTagIndex + lengthOfEndMsg;
string subStr = msg.Substring(0, endOfEndTag); //message statrs with start tag and ends contains full end tag so first get that string and send that.
content.Append(subStr);
CheckSendMessage(workSocket);
//Parse the remaining message from endtag+1 to end
ParseIncomingMessage(msg.Substring(endOfEndTag, msg.Length - endOfEndTag), wrkSocket);
}
else
{
content.Append(msg);
}
}
}
//if message contains EndTag ALONE
else if (hasEndTag)
{
int endOfEndTag = endTagIndex + lengthOfEndMsg;
string subStr = msg.Substring(0, endOfEndTag);
content.Append(subStr);
CheckSendMessage(workSocket);
//Parse remaining message after end tag
ParseIncomingMessage(msg.Substring(endOfEndTag, msg.Length - endOfEndTag), wrkSocket);
}
}
private void CheckSendMessage(Socket workSocket)
{
string msg=content.ToString().Trim();
//if content contains both start and end tag then send the content
if (isMsgContainsStartTag(msg) && isMsgContainsEndTag(msg) &&
indexOfStartTag(msg) == 0 && indexOfEndTag(msg) + lengthOfEndMsg == msg.Length)
{
//Send the message
using (MedDeviceListenerEventArgs e = new MedDeviceListenerEventArgs(msg))
{
OnReceiveComplete(e);
SendReceiveAck(workSocket, _receiveAckMessage);
}
}
}
private void SendReceiveAck(Socket handler, String data)
{
try
{
ProfileProvider.Instance.LogInformationIf(_debug);
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
handler.Send(byteData);
InstrumentationProvider.Instance.LogInformationIf(_debug, "Message received acknowledgement:" + _receiveAckMessage + " has been sent successfully");
}
catch (Exception ex)
{
InstrumentationProvider.Instance.LogException("SendReceiveAck", ex);
}
}
private void SendConnectedAck(string msg, int clientNumber)
{
ProfileProvider.Instance.LogInformationIf(_debug);
try
{
// Convert the reply to byte array
byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg);
Socket workerSocket = (Socket)workerSocketList[clientNumber - 1];
workerSocket.Send(byData);
InstrumentationProvider.Instance.LogInformationIf(_debug, "Client Connected acknowledgement:" + _clientConnectAckMessage + " has been sent successfully");
}
catch (Exception ex)
{
InstrumentationProvider.Instance.LogException("SendConnectedAck", ex);
throw;
}
}
public void CloseSockets()
{
try
{
ProfileProvider.Instance.LogInformationIf(_debug);
if (m_mainSocket != null)
{
if (m_mainSocket.Connected)
{
m_mainSocket.Shutdown(SocketShutdown.Both);
m_mainSocket.Close();
m_mainSocket = null;
}
}
Socket workerSocket = null;
for (int i = 0; i < workerSocketList.Count; i++)
{
workerSocket = (Socket)workerSocketList[i];
if (workerSocket != null)
{
workerSocket.Shutdown(SocketShutdown.Both);
workerSocket.Close();
workerSocket = null;
}
}
}
catch(Exception ex)
{
InstrumentationProvider.Instance.LogException("CloseSockets",ex);
}
}
protected virtual void OnReceiveComplete(MedDeviceListenerEventArgs e)
{
if (MessageReceived != null)
{
MessageReceived(this, e);
}
}
private int indexOfStartTag(string msg)
{
return msg.IndexOf(header);
}
private int indexOfEndTag(string msg)
{
return msg.IndexOf(footer);
}
private bool isMsgContainsStartTag(string msg)
{
return msg.Contains(header);
}
private bool isMsgContainsEndTag(string msg)
{
return msg.Contains(footer);
}
public delegate void MessageReceiveEventHandler(object sender,MedDeviceListenerEventArgs e);
public class MedDeviceListenerEventArgs : EventArgs,IDisposable
{
private string _receivedData;
public MedDeviceListenerEventArgs(string receivedData)
{
_receivedData = receivedData;
}
public string ReceivedData
{
get
{
return _receivedData;
}
}
public void Dispose()
{ }
}
}
I have read similar posts, tried everything but with no luck. Please help :)
Thanks
-MM

C# Sockets: 2nd (and more) users can't connect

I connect to my (C#) server and from an App built in Corona SDK but for the second person can never connect.
I have tried using different IP's i.e. two cellphones with external IP's with no difference.
This is how my server listener works:
server.cs
void Listener()
{
while (isRunning)
{
try
{
Socket socket = listener.AcceptSocket();
foreach (var worker in workers)
if (worker.IsAvailable)
{
worker.ProcessNewSocket(socket);
break;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
public void Run()
{
Console.WriteLine("Server.Run()");
listener.Start();
isRunning = true;
foreach (var worker in workers)
{
Thread t = new Thread(worker.Run);
t.Start();
}
Listener();
}
ServerWorker.cs
public void ProcessNewSocket(Socket socket)
{
var pc = new PlayerClient(this);
sockets.Add(socket, pc);
}
// this method will be called in cycle
public void Run()
{
while (server.IsRunning)
{
List<Socket> readList = sockets.Keys.ToList(); //List of sockets that have some data from client available for reading.
List<Socket> writeList = sockets.Keys.ToList(); //List of sockets that are ready to write (send) to the client. An action was made to a table and the change was sent to PlayerClient.Write and is now stored in the queue (MemoreStream)
List<Socket> errorList = sockets.Keys.ToList();
if (readList.Count() != 0 || writeList.Count() != 0 || errorList.Count() != 0)
{
// for providing security you can use System.Net.Security.SslStream here when read/write data,
// see http://msdn.microsoft.com/ru-ru/library/system.net.security.sslstream(v=vs.110).aspx
Socket currentSocket = null;
// foreach socket with events
try
{
foreach (var s in readList)
{
currentSocket = s;
//TODO: Get the actual length of the message.
byte[] data = new byte[2048];
s.Receive(data);
sockets[s].OnData(data);
}
foreach (var s in writeList)
{
currentSocket = s;
if (sockets[s].IsWriteDataAvailable())
{
s.Send(sockets[s].GetWriteBuffer());
sockets[s].ClearWriteBuffer();
}
}
foreach (var s in errorList)
{
//OnError
}
}
// we got exception, depending on the type...
catch (SocketException ex)
{
//Console.WriteLine(ex.ToString());
// send client error message, this is not always possible(for example network failure)
// maybe we would like to notify his opponent about connection failure
// terminate connection
if (ex.ErrorCode == (int)SocketError.ConnectionAborted || ex.ErrorCode == (int)SocketError.ConnectionReset)
RemoveSocket(currentSocket);
else
Console.WriteLine("Other problem .. " + ex.ErrorCode.ToString());
}
}
}
}
I'm new in network programming so I'm not really sure what to do. I have read about using ASync but first I would like to know if there is something I can do with this code and/or if I should change it completely?
I think the "BREAK" statement in your Listener() Block;
foreach (var worker in workers)
if (worker.IsAvailable)
{
worker.ProcessNewSocket(socket);
break; // this BREAK WILL END YOUR loop AFTER first CLIENT FOUND.
}
So, try removing break as;
foreach (var worker in workers)
{
if (worker.IsAvailable)
{
worker.ProcessNewSocket(socket);
}
}

TCP - C# - Server Client Chat Compare

I have managed to create a Server/Client chat system, where the client sends a message to the server and the the server sends the message to all the clients.
I want to extend this so that the Server compares the messages and then sends a message to the client.
For Example: If client 1 sends 10 and client 2 sends 20 the server will compare these and the server will send a message saying 20 is more than 10.
Is this possible to do? And if so how?
Server Code:
namespace Server
{
public partial class Form1 : Form
{
private const int m_iMaxConnections = 2;
struct Connection_Struct // Define a structure to hold details about a single connection
{
public Socket ClientSpecific_Socket;
public bool bInUse;
};
Socket m_ListenSocket;
Socket m_SendSocket;
Connection_Struct[] m_Connection_Array = new Connection_Struct[m_iMaxConnections]; // Define an array to hold a number of connections
System.Net.IPEndPoint m_LocalIPEndPoint;
static int m_iNumberOfConnectedClients;
private static System.Windows.Forms.Timer m_CommunicationActivity_Timer;
public Form1()
{
InitializeComponent();
Initialise_ConnectionArray();
m_CommunicationActivity_Timer = new System.Windows.Forms.Timer(); // Check for communication activity on Non-Blocking sockets every 200ms
m_CommunicationActivity_Timer.Tick += new EventHandler(OnTimedEvent_PeriodicCommunicationActivityCheck); // Set event handler method for timer
m_CommunicationActivity_Timer.Interval = 100; // Timer interval is 1/10 second
m_CommunicationActivity_Timer.Enabled = false;
string szLocalIPAddress = GetLocalIPAddress_AsString(); // Get local IP address as a default value
txtIPAddress.Text = szLocalIPAddress; // Place local IP address in IP address field
txtPort.Text = "8000"; // Default port number
m_iNumberOfConnectedClients = 0;
txtClientNo.Text = System.Convert.ToString(m_iNumberOfConnectedClients);
try
{ // Create the Listen socket, for TCP use
m_ListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_ListenSocket.Blocking = false;
m_SendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Tcp);
}
catch (SocketException se)
{ // If an exception occurs, display an error message
MessageBox.Show(se.Message);
}
}
private void Initialise_ConnectionArray()
{
int iIndex;
for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
{
m_Connection_Array[iIndex].bInUse = false;
}
}
private void btnEnableServer_Click(object sender, EventArgs e)
{
// Bind to the selected port and start listening / receiving
try
{
// Get the Port number from the appropriate text box
String szPort = txtPort.Text;
int iPort = System.Convert.ToInt16(szPort, 10);
// Create an Endpoint that will cause the listening activity to apply to all the local node's interfaces
m_LocalIPEndPoint = new System.Net.IPEndPoint(IPAddress.Any, iPort);
// Bind to the local IP Address and selected port
m_ListenSocket.Bind(m_LocalIPEndPoint);
txtLog.Text = "Bind succeded";
// Prevent any further changes to the port number
txtPort.ReadOnly = true;
}
catch // Catch any errors
{ // If an exception occurs, display an error message
txtLog.Text = "Bind failed";
}
try
{
txtLog.Text = "Listening";
m_ListenSocket.Listen(2); // Listen for connections, with a backlog / queue maximum of 2
}
catch (SocketException se)
{
// If an exception occurs, display an error message
MessageBox.Show(se.Message);
}
catch // Silently handle any other exception
{
}
m_CommunicationActivity_Timer.Start(); // Start the timer to perform periodic checking for connection requests
txtLog.Text = "Accepting (waiting for connection attempt)";
btnEnableServer.Enabled = false;
}
private void OnTimedEvent_PeriodicCommunicationActivityCheck(Object myObject, EventArgs myEventArgs)
{ // Periodic check whether a connection request is pending or a message has been received on a connected socket
// First, check for pending connection requests
int iIndex;
iIndex = GetnextAvailable_ConnectionArray_Entry(); // Find an available array entry for next connection request
if (-1 != iIndex)
{ // Only continue with Accept if there is an array entry available to hold the details
try
{
m_Connection_Array[iIndex].ClientSpecific_Socket = m_ListenSocket.Accept(); // Accept a connection (if pending) and assign a new socket to it (AcceptSocket)
// Will 'catch' if NO connection was pending, so statements below only occur when a connection WAS pending
m_Connection_Array[iIndex].bInUse = true;
m_Connection_Array[iIndex].ClientSpecific_Socket.Blocking = false; // Make the new socket operate in non-blocking mode
m_iNumberOfConnectedClients++;
txtClientNo.Text = System.Convert.ToString(m_iNumberOfConnectedClients);
txtLog.Text = "A new client connected";
SendUpdateMesageToAllConnectedclients();
}
catch (SocketException se) // Handle socket-related exception
{ // If an exception occurs, display an error message
if (10053 == se.ErrorCode || 10054 == se.ErrorCode) // Remote end closed the connection
{
CloseConnection(iIndex);
}
else if (10035 != se.ErrorCode)
{ // Ignore error messages relating to normal behaviour of non-blocking sockets
MessageBox.Show(se.Message);
}
}
catch // Silently handle any other exception
{
}
}
// Second, check for received messages on each connected socket
for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
{
if (true == m_Connection_Array[iIndex].bInUse)
{
try
{
EndPoint localEndPoint = (EndPoint)m_LocalIPEndPoint;
byte[] ReceiveBuffer = new byte[1024];
int iReceiveByteCount;
iReceiveByteCount = m_Connection_Array[iIndex].ClientSpecific_Socket.ReceiveFrom(ReceiveBuffer, ref localEndPoint);
string szReceivedMessage;
if (0 < iReceiveByteCount)
{ // Copy the number of bytes received, from the message buffer to the text control
szReceivedMessage = Encoding.ASCII.GetString(ReceiveBuffer, 0, iReceiveByteCount);
if ("QuitConnection" == szReceivedMessage)
{
CloseConnection(iIndex);
}
else
{
txtLog.AppendText(szReceivedMessage + Environment.NewLine);
// Send message to each connected client.
// int iIndex2;
for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
{
if (true == m_Connection_Array[iIndex].bInUse)
{
string szMessage;
szMessage = szReceivedMessage;
txtLog.Text = m_Connection_Array[m_iMaxConnections].ToString();
byte[] SendMessage = System.Text.Encoding.ASCII.GetBytes(szMessage);
m_Connection_Array[iIndex].ClientSpecific_Socket.Send(SendMessage, SocketFlags.None);
}
}
}
}
}
catch (SocketException se) // Handle socket-related exception
{ // If an exception occurs, display an error message
if (10053 == se.ErrorCode || 10054 == se.ErrorCode) // Remote end closed the connection
{
CloseConnection(iIndex);
}
else if (10035 != se.ErrorCode)
{ // Ignore error messages relating to normal behaviour of non-blocking sockets
MessageBox.Show(se.Message);
}
}
catch // Silently handle any other exception
{
}
}
}
}
private void SendUpdateMesageToAllConnectedclients()
{ // Send message to each connected client informing of the total number of connected clients
int iIndex;
for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
{
if (true == m_Connection_Array[iIndex].bInUse)
{
string szMessage;
if (1 == m_iNumberOfConnectedClients)
{
szMessage = string.Format("There is now {0} client connected", m_iNumberOfConnectedClients);
}
else
{
szMessage = string.Format("There are now {0} clients connected", m_iNumberOfConnectedClients);
}
byte[] SendMessage = System.Text.Encoding.ASCII.GetBytes(szMessage);
m_Connection_Array[iIndex].ClientSpecific_Socket.Send(SendMessage, SocketFlags.None);
}
}
}
private void CloseConnection(int iIndex)
{
try
{
m_Connection_Array[iIndex].bInUse = false;
m_Connection_Array[iIndex].ClientSpecific_Socket.Shutdown(SocketShutdown.Both);
m_Connection_Array[iIndex].ClientSpecific_Socket.Close();
m_iNumberOfConnectedClients--;
txtClientNo.Text = System.Convert.ToString(m_iNumberOfConnectedClients);
txtLog.Text = "A Connection was closed";
SendUpdateMesageToAllConnectedclients();
}
catch // Silently handle any exceptions
{
}
}
private void Close_And_Quit()
{ // Close the sockets and exit the application
try
{
m_ListenSocket.Close();
}
catch
{
}
try
{
int iIndex;
for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
{
m_Connection_Array[iIndex].ClientSpecific_Socket.Shutdown(SocketShutdown.Both);
m_Connection_Array[iIndex].ClientSpecific_Socket.Close();
}
}
catch
{
}
try
{
Close();
}
catch
{
}
}
public string GetLocalIPAddress_AsString()
{
string szHost = Dns.GetHostName();
string szLocalIPaddress = "127.0.0.1"; // Default is local loopback address
IPHostEntry IPHost = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress IP in IPHost.AddressList)
{
if (IP.AddressFamily == AddressFamily.InterNetwork) // Match only the IPv4 address
{
szLocalIPaddress = IP.ToString();
break;
}
}
return szLocalIPaddress;
}
private int GetnextAvailable_ConnectionArray_Entry()
{
int iIndex;
for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
{
if (false == m_Connection_Array[iIndex].bInUse)
{
return iIndex; // Return the index value of the first not-in-use entry found
}
}
return -1; // Signal that there were no available entries
}
}
}
Client Code:
namespace Client
{
public partial class Form1 : Form
{
Socket m_ClientSocket;
System.Net.IPEndPoint m_remoteEndPoint;
IPEndPoint m_localIPEndPoint;
Socket m_ReceiveSocket;
private static System.Windows.Forms.Timer m_CommunicationActivity_Timer;
public Form1()
{
InitializeComponent();
m_CommunicationActivity_Timer = new System.Windows.Forms.Timer(); // Check for communication activity on Non-Blocking sockets every 200ms
m_CommunicationActivity_Timer.Tick += new EventHandler(OnTimedEvent_PeriodicCommunicationActivityCheck); // Set event handler method for timer
m_CommunicationActivity_Timer.Interval = 100; // Timer interval is 1/10 second
m_CommunicationActivity_Timer.Enabled = false;
string szLocalIPAddress = GetLocalIPAddress_AsString(); // Get local IP address as a default value
txtIPAddress.Text = szLocalIPAddress; // Place local IP address in IP address field
txtPort.Text = "8000"; // Default port number
}
private void btnConnect_Click(object sender, EventArgs e)
{
// Connect the Socket with a remote endpoint
try
{
// Create the socket, for TCP use
m_ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_ClientSocket.Blocking = true; // Socket operates in Blocking mode initially
}
catch // Handle any exceptions
{
Close_Socket_and_Exit();
}
try
{
// Get the IP address from the appropriate text box
String szIPAddress = txtIPAddress.Text;
System.Net.IPAddress DestinationIPAddress = System.Net.IPAddress.Parse(szIPAddress);
// Get the Port number from the appropriate text box
String szPort = txtPort.Text;
int iPort = System.Convert.ToInt16(szPort, 10);
// Combine Address and Port to create an Endpoint
m_remoteEndPoint = new System.Net.IPEndPoint(DestinationIPAddress, iPort);
m_ClientSocket.Connect(m_remoteEndPoint);
m_ClientSocket.Blocking = false; // Socket is now switched to Non-Blocking mode for send/ receive activities
txtLog.Text = "Connected";
m_CommunicationActivity_Timer.Start(); // Start the timer to perform periodic checking for received messages
}
catch // Catch all exceptions
{ // If an exception occurs, display an error message
txtLog.Text = "(Connect attempt failed)\nRetry Connect";
}
}
private void OnTimedEvent_PeriodicCommunicationActivityCheck(Object myObject, EventArgs myEventArgs)
{ // Periodic check whether a message has been received
try
{
EndPoint RemoteEndPoint = (EndPoint)m_remoteEndPoint;
byte[] ReceiveBuffer = new byte[1024];
int iReceiveByteCount;
iReceiveByteCount = m_ClientSocket.ReceiveFrom(ReceiveBuffer, ref RemoteEndPoint);
string szReceivedMessage;
if (0 < iReceiveByteCount)
{ // Copy the number of bytes received, from the message buffer to the text control
szReceivedMessage = Encoding.ASCII.GetString(ReceiveBuffer, 0, iReceiveByteCount);
txtResult.Text = szReceivedMessage;
}
}
catch // Silently handle any exceptions
{
}
}
private void Close_Socket_and_Exit()
{
try
{
m_ClientSocket.Shutdown(SocketShutdown.Both);
}
catch // Silently handle any exceptions
{
}
try
{
m_ClientSocket.Close();
}
catch // Silently handle any exceptions
{
}
this.Close();
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
try
{
String szData = "QuitConnection"; // Special code to signal 'close connection' to the server
// This ensures that the server is aware the Client wants to close the connection
// (TCP should otherwise automatically detect disconnection, but this approach ensures a clean disconnect)
byte[] byData = System.Text.Encoding.ASCII.GetBytes(szData);
m_ClientSocket.Send(byData, SocketFlags.None);
m_ClientSocket.Shutdown(SocketShutdown.Both);
m_ClientSocket.Close();
btnConnect.Text = "Connect";
txtResult.Text = "";
}
catch // Silently handle any exceptions
{
}
}
private string GetLocalIPAddress_AsString()
{
string szHost = Dns.GetHostName();
string szLocalIPaddress = "127.0.0.1"; // Default is local loopback address
IPHostEntry IPHost = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress IP in IPHost.AddressList)
{
if (IP.AddressFamily == AddressFamily.InterNetwork) // Match only the IPv4 address
{
szLocalIPaddress = IP.ToString();
break;
}
} return szLocalIPaddress;
}
}
}

Sockets: Send strings from Java to C#?

I need to send string messages from Java program to C# program in real time.
There are many examples in the Internet but U can't find anything good for my purpose that is (probably) Java client (sockets code) and c# server (sockets code).
Thank you.
Ok i already did this in one of my projects so here it is:
disclaimer: some of the code (only a little bit actually) is based on nakov chat server.
also note that i decode and encode all the messages sent and recived in UTF-8.
Java Code:
Class: Server
import java.net.*;
import java.io.*;
import javax.swing.*;
public class Server
{
private static void createAndShowGUI() {
//Create and set up the window
}
public static final int LISTENING_PORT = 2002;
public static void main(String[] args)
{
// Open server socket for listening
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(LISTENING_PORT);
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
//System.out.println("Server started on port " + LISTENING_PORT);
}
catch (IOException se)
{
System.err.println("Can not start listening on port " + LISTENING_PORT);
se.printStackTrace();
System.exit(-1);
}
// Start ServerDispatcher thread
ServerDispatcher serverDispatcher = new ServerDispatcher();
// Accept and handle client connections
while (true)
{
try
{
Socket socket = serverSocket.accept();
ClientInfo clientInfo = new ClientInfo();
clientInfo.mSocket = socket;
ClientListener clientListener =
new ClientListener(clientInfo, serverDispatcher);
ClientSender clientSender =
new ClientSender(clientInfo, serverDispatcher);
clientInfo.mClientListener = clientListener;
clientInfo.mClientSender = clientSender;
clientListener.start();
clientSender.start();
serverDispatcher.addClient(clientInfo);
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
}
Class Message Dispatcher:
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.util.*;
public class ServerDispatcher
{
private Vector mMessageQueue = new Vector();
private Vector<ClientInfo> mClients = new Vector<ClientInfo>();
public synchronized void addClient(ClientInfo aClientInfo) {
mClients.add(aClientInfo);
}
public synchronized void deleteClient(ClientInfo aClientInfo) {
int clientIndex = mClients.indexOf(aClientInfo);
if (clientIndex != -1)
mClients.removeElementAt(clientIndex);
}
private synchronized void sendMessageToAllClients(String aMessage)
{
for (int i = 0; i < mClients.size(); i++) {
ClientInfo infy = (ClientInfo) mClients.get(i);
infy.mClientSender.sendMessage(aMessage);
}
}
public void sendMessage(ClientInfo aClientInfo, String aMessage) {
aClientInfo.mClientSender.sendMessage(aMessage);
}
}
Class: ClientInfo
/**
*
* ClientInfo class contains information about a client, connected to the server.
*/
import java.awt.List;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Vector;
public class ClientInfo
{
public int userID=-1;
public Socket mSocket = null;
public ClientListener mClientListener = null;
public ClientSender mClientSender = null;
}
Class ClientListner:
/**
* ClientListener class is purposed to listen for client messages and
* to forward them to ServerDispatcher.
*/
import java.io.*;
import java.net.*;
public class ClientListener extends Thread {
private ServerDispatcher mServerDispatcher;
private ClientInfo mClientInfo;
private BufferedReader mIn;
private String message;
private String decoded = null;
public ClientListener(ClientInfo aClientInfo,
ServerDispatcher aServerDispatcher) throws IOException {
mClientInfo = aClientInfo;
mServerDispatcher = aServerDispatcher;
Socket socket = aClientInfo.mSocket;
mIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
/**
* Until interrupted, reads messages from the client socket, forwards them
* to the server dispatcher and notifies the server dispatcher.
*/
public void run() {
message = "";
while (!isInterrupted()) {
try {
message = mIn.readLine();
if (message == null)
break;
try {
decoded = URLDecoder.decode(message, "UTF-8");
} catch (UnsupportedEncodingException e)
e.printStackTrace();
}
mServerDispatcher.sendMessage(mClientInfo, decoded);
}
catch (IOException e) {
break;
}
}
// Communication is broken. Interrupt both listener and sender threads
mClientInfo.mClientSender.interrupt();
mServerDispatcher.deleteClient(mClientInfo);
}
}
Class:ClientSender
/**
* Sends messages to the client. Messages are stored in a message queue. When
* the queue is empty, ClientSender falls in sleep until a new message is
* arrived in the queue. When the queue is not empty, ClientSender sends the
* messages from the queue to the client socket.
*/
import java.io.*;
import java.net.*;
import java.util.*;
public class ClientSender extends Thread
{
private Vector mMessageQueue = new Vector();
private ServerDispatcher mServerDispatcher;
private ClientInfo mClientInfo;
private PrintWriter mOut;
public ClientSender(ClientInfo aClientInfo, ServerDispatcher aServerDispatcher)
throws IOException
{
mClientInfo = aClientInfo;
mServerDispatcher = aServerDispatcher;
Socket socket = aClientInfo.mSocket;
mOut = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
}
/**
* Adds given message to the message queue and notifies this thread
* (actually getNextMessageFromQueue method) that a message is arrived.
* sendMessage is called by other threads (ServeDispatcher).
*/
public synchronized void sendMessage(String aMessage)
{
mMessageQueue.add(aMessage);
notify();
}
/**
* #return and deletes the next message from the message queue. If the queue
* is empty, falls in sleep until notified for message arrival by sendMessage
* method.
*/
private synchronized String getNextMessageFromQueue() throws InterruptedException
{
while (mMessageQueue.size()==0)
wait();
String message = (String) mMessageQueue.get(0);
mMessageQueue.removeElementAt(0);
return message;
}
/**
* Sends given message to the client's socket.
*/
private void sendMessageToClient(String aMessage)
{
String encoded;
try {
encoded = URLEncoder.encode(aMessage,"UTF-8");
mOut.println(encoded);
mOut.flush();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Until interrupted, reads messages from the message queue
* and sends them to the client's socket.
*/
public void run()
{
try {
while (!isInterrupted()) {
String message = getNextMessageFromQueue();
sendMessageToClient(message);
}
} catch (Exception e) {
// Commuication problem
break;
}
// Communication is broken. Interrupt both listener and sender threads
mClientInfo.mClientListener.interrupt();
mServerDispatcher.deleteClient(mClientInfo);
}
}
Ok this is the java code,now to the c# code
c# Code:
Varibales used:
private StreamWriter swSender;
private StreamReader srReceiver;
private TcpClient tcpServer;
private Thread thrMessaging;
private IPAddress ipAddr;
private bool Connected;
Function: Intelize connection:
private void InitializeConnection()
{
// Parse the IP address
string ipAdress = "XXX.XXX.XXX.XXX";
ipAddr = IPAddress.Parse(ipAdress);
// Start a new TCP connections to the chat server
tcpServer = new TcpClient();
try
{
tcpServer.Connect(ipAddr, 2002);
swSender = new StreamWriter(tcpServer.GetStream());
// Start the thread for receiving messages and further communication
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
Connected=true;
}
catch (Exception e2)
{
MessageBox.Show(e2.ToString());
}
}
}
Function: ReciveMessages
private void ReceiveMessages()
{
// Receive the response from the server
srReceiver = new StreamReader(tcpServer.GetStream());
while (Connected)
{
String con = srReceiver.ReadLine();
string StringMessage = HttpUtility.UrlDecode(con, System.Text.Encoding.UTF8);
processMessage(StringMessage);
}
}
Function: proceesMessage:
private void processMessage(String p)
{
// do something with the message
}
Function sendMessage:
private void SendMessage(String p)
{
if (p != "")
{
p = HttpUtility.UrlEncode(p, System.Text.Encoding.UTF8);
swSender.WriteLine(p);
swSender.Flush();
}
}
thats it thats all you need to have communication between java server and c# client. if you have any questions dont hesitate to post them here.
Choose a protocol for encoding/sending your strings. For instance:
<length of string (4 bytes)><string data (length bytes)>
Write some Java code to send a string that follows whatever protocol you chose in #1. So using the example above, you could do something like:
public static void writeString(String string, OutputStream out) throws IOEXception {
if (string == null || "".equals(string)) {
//nothing to do
return;
}
int length = string.length();
//synchronize so that two threads don't try to write to the same stream at the same time
synchronized(out) {
out.write((length >> 24) & 0xFF);
out.write((length >> 16) & 0xFF);
out.write((length >> 8) & 0xFF);
out.write(length & 0xFF);
out.write(string.getBytes());
out.flush();
}
}
Write some equivalent code in C# to decode the strings that are being sent. It will look a lot like your Java code, except with reads instead of writes.
I think I've found a good, working solution. Using UDP sockets:
Java code
public void runJavaSocket() {
System.out.println("Java Sockets Program has started."); int i=0;
try {
DatagramSocket socket = new DatagramSocket();
System.out.println("Sending the udp socket...");
// Send the Message "HI"
socket.send(toDatagram("HI",InetAddress.getByName("127.0.0.1"),3800));
while (true) {
System.out.println("Sending hi " + i);
Thread.currentThread();
Thread.sleep(1000);
socket.send(toDatagram("HI " +
String.valueOf(i),InetAddress.getByName("127.0.0.1"),3800));
i++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public DatagramPacket toDatagram(
String s, InetAddress destIA, int destPort) {
// Deprecated in Java 1.1, but it works:
byte[] buf = new byte[s.length() + 1];
s.getBytes(0, s.length(), buf, 0);
// The correct Java 1.1 approach, but it's
// Broken (it truncates the String):
// byte[] buf = s.getBytes();
return new DatagramPacket(buf, buf.length, destIA, destPort);
}
C# code
string returnData;
byte[] receiveBytes;
//ConsoleKeyInfo cki = new ConsoleKeyInfo();
using (UdpClient udpClient =
new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3800)))
{
IPEndPoint remoteIpEndPoint =
new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3800);
while (true)
{
receiveBytes = udpClient.Receive(ref remoteIpEndPoint);
returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine(returnData);
}
}
I would just use SOAP protocol. You can use WCF on the C# side and JMS (Java messging) on the Java side. Both these technologies are built on SOAP so they can read each other's messages. They both use WSDL.

Categories

Resources