first: I hope my english is not so bad (maybe it's gerglish; german grammer with english vocabularies)
I'm writing an server in java for android which communicates with an client written in c# running on WindowsCE 5. The big problem is that sometimes especially or maybe only if the network is unstable my java server still blocks in the accept-Method also when the client is sending data. I simulated the unstable network by switch off and on my virtual router over which both devices communicate. I also could recognize that the c#-program hangs in the write- or read-method or throws an IOException also when the network is switched on and my server is hearing on the expected port.
Here is the source code of the client:
Some information:
1. It is sending 10000 messages only for testing
static void Main(string[] args)
{
string server = ...;
int port = 12000;
String outputStr = "";
NetworkStream stream = null;
for (int i = 0; i < 10000; i++)
{
TcpClient client = null;
String messageToSend = ...
try
{
IPAddress ipAddress = IPAddress.Parse(server);
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
AutoResetEvent connectDone = new AutoResetEvent(false);
client = new TcpClient();
client.Client.BeginConnect(ipEndPoint,
new AsyncCallback(
delegate(IAsyncResult ar)
{
try
{
client.Client.EndConnect(ar);
connectDone.Set();
}
catch (Exception ex)
{}
}
), client.Client);
if (!connectDone.WaitOne(5000, false))
{
outputStr = "NOTConnected";
}
Byte[] data = System.Text.Encoding.UTF8.GetBytes(messageToSend);
stream = client.GetStream();
try
{
stream.Write(data, 0, data.Length);
data = new Byte[2048];
int bytes = stream.Read(data, 0, data.Length);
string responseData = System.Text.Encoding.UTF8.GetString(data, 0, bytes);
outputStr = responseData;
}
catch (IOException ex)
{
outputStr = ex.Message;
}
}
}
catch (SocketException ex)
{
outputStr = ex.Message;
}
catch (Exception ex)
{
outputStr = ex.Message;
}
finally
{
if (stream != null) stream.Close();
}
System.Threading.Thread.Sleep(200);
}
Console.WriteLine("\n Press Enter to continue... " + outputStr);
Console.Read();
}
And my source code of the server:
Some information. My servlet normally is an inner class and first checks if the devices is connected to a router. If it is it starting to here on a port. If not it goes to wait mode (see _sendToSleep()). If devices is reconnected the activity can wakes it up by notify. If it looses again the connection the Activity will cause a SocketException by closing the socket so the servlet can leave the accept-method.
public class ServletThread extends Thread {
private int port;
private ServerSocket serverSocket;
private Socket socket;
public ServletThread(int port) throws IOException {
super();
this.port = port;
serverSocket = new ServerSocket(port);
}
private void checkConnectivity(BufferedWriter out) {
try {
String outgoingMsg = "connected";
out.write(outgoingMsg);
out.flush();
} catch (IOException e) {
Log.e(TAG, "connectivity exception " + e.getMessage());
}
}
private void readStream(Scanner scanner) throws IOException {
String str = "";
while (scanner.hasNext()) {
str += scanner.nextLine();
}
final String fTicket = str;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (MyActivity.this.isFinishing()) {
return;
}
// do something
}
});
}
private void _sendToSleep() {
try {
synchronized (this) {
this.wait();
}
} catch (InterruptedException e) {
this.interrupt();
}
}
#Override
public void interrupt() {
super.interrupt();
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
Log.e(TAG, ""+e.getMessage());
}
}
}
#Override
public void run() {
try {
serverSocket = new ServerSocket(port);
} catch (IOException ex) {
Log.e(TAG,""+ex.getMessage());
}
while (!isInterrupted()) {
if (connectionState != NetworkInfo.State.CONNECTED) {
_sendToSleep();
} else {
BufferedWriter out = null;
Scanner scanner = null;
try {
socket = serverSocket.accept();
out = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
scanner = new Scanner(socket.getInputStream());
checkConnectivity(out);
readStream(scanner);
} catch (IOException ex) {
Log.e(TAG, ex.getMessage() + "");
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "exception on close socket " + e.getMessage());
}
}
if (scanner != null) {
scanner.close();
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
Log.e(TAG, ""+e.getMessage());
}
}
}
}
}
}
}
After isolating the bug, i did some changes:
c# instead of stream = client.getStream
(using Stream = client.getStream()) {
...
stream.WriteTimeout = 1000;
stream.ReadTimeout = 1000;
...
}
in java changes in the _sendToSleep()
private void _sendToSleep() {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
Log.e(TAG, "failed to close serverSocket " + e.getMessage());
}
}
try {
synchronized (this) {
this.wait();
}
} catch (InterruptedException e) {
this.interrupt();
}
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
Log.e(TAG, "failed to open serversocket " + e.getMessage());
}
}
It became better, means, I could not reproduce the problem.
My questions:
Why did it the client hang? (maybe a synchronisation problem on servlet-side and client between socketserver and wlan-adapter after reconnecting several times, so that the servlet cannot get any data???)
And do my changes solve the problem.
Thanking you in anticipation!
Related
I have created these applications. One is server socket which consists of main thread responsible for creating client/server connection and creating other threads:
thread for producing messages
thread for listening for received messages from client
thread to send produced messages by server
If there is connection disrupted server frees any resources and waits for new connections in a loop.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class SynchronousSocketListener {
private Socket handler; //socket handlet
private byte[] bytes; // Data buffer for incoming data.
private List < String > messagesToSend;
private Mutex messagesToSendMutex;
public SynchronousSocketListener() {
messagesToSendMutex = new Mutex();
try {
messagesToSendMutex.WaitOne();
messagesToSend = new List < String > ();
} finally {
messagesToSendMutex.ReleaseMutex();
}
bytes = new Byte[1024];
handler = null;
}
private void addMessageToQueue(string message) {
try {
messagesToSendMutex.WaitOne();
messagesToSend.Add(message);
} finally {
messagesToSendMutex.ReleaseMutex();
}
}
private string readMessageFromQueue() {
string ret = null;
try {
messagesToSendMutex.WaitOne();
if (messagesToSend.Count > 0)
ret = messagesToSend[0];
} finally {
messagesToSendMutex.ReleaseMutex();
}
return ret;
}
private void removeMessageFromQueue(string messageToRemove) {
string ret = null;
try {
messagesToSendMutex.WaitOne();
if (messagesToSend.Count > 0)
messagesToSend.Remove(messageToRemove);
} finally {
messagesToSendMutex.ReleaseMutex();
}
}
private void threadForGeneratingMessages() {
while (true) {
addMessageToQueue(Console.ReadLine());
}
}
private void sendingThread(CancellationToken ct) {
while (true) {
try {
if (ct.IsCancellationRequested) {
// Clean up here, then...
ct.ThrowIfCancellationRequested();
Console.WriteLine("Task sending is cancelled");
return;
}
} catch (System.OperationCanceledException ex) {
Console.WriteLine("System.OperationCanceledException");
return;
}
if (messagesToSend.Count <= 0) {
Console.WriteLine("No more messages to send");
Thread.Sleep(5000);
continue;
}
Console.WriteLine("Server is going to write some data for client");
//send pending messages to client
string dataToSendNow = messagesToSend[0];
byte[] msg = Encoding.ASCII.GetBytes(dataToSendNow + "<EOF>");
try {
// Send the data through the socket.
int bytesSent = handler.Send(msg);
messagesToSend.Remove(dataToSendNow);
Console.WriteLine("Server send data");
} catch (SocketException ex) {
Console.WriteLine(ex.ToString());
Console.WriteLine("returning from sendingThread sockEx");
return;
} catch (ObjectDisposedException ex) {
Console.WriteLine(ex.ToString());
//socketError = true;
Console.WriteLine("returning from sendingThread objDisEx");
return;
}
Thread.Sleep(100);
}
}
private void receivingThread(CancellationToken ct) {
while (true) {
try {
if (ct.IsCancellationRequested) {
// Clean up here, then...
ct.ThrowIfCancellationRequested();
Console.WriteLine("Task receiving is cancelled");
return;
}
} catch (System.OperationCanceledException ex) {
Console.WriteLine("System.OperationCanceledException");
return;
}
Console.WriteLine("Server is waiting for a new message to arrive: ");
try {
if (!handler.Connected) throw new SocketException();
//handler.Send(new byte[] { 0 });
int bytesRec = handler.Receive(bytes);
string receivedData = Encoding.ASCII.GetString(bytes, 0, bytesRec);
Console.WriteLine("Server has received message = {0}",
receivedData);
/*
//do some stuff with the message
.
.
.
*/
} catch (SocketException ex) {
Console.WriteLine(ex.ToString());
//socketError = true;
return;
} catch (ObjectDisposedException ex) {
Console.WriteLine(ex.ToString());
//socketError = true;
return;
}
}
}
public void StartListening() {
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
while (true) {
// Create a TCP/IP socket.
// Bind the socket to the local endpoint and
// listen for incoming connections.
Socket listener = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
Console.WriteLine("New connection can be made");
try {
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11100);
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
handler = listener.Accept();
Console.WriteLine("New connection is made");
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
//when new connection is made create new thread for sending data through socket
var task_send = Task.Run(() => {
sendingThread(ct);
}, tokenSource2.Token);
var tokenSource3 = new CancellationTokenSource();
CancellationToken ct3 = tokenSource3.Token;
//when new connection is made create new thread for receiving data through socket
var task = Task.Run(() => {
receivingThread(ct3);
}, tokenSource3.Token);
while (true) {
if (task.IsCompleted || task_send.IsCompleted) { //activelly oolling the field to find out, wether threads has been cancelled/returned
Console.WriteLine("some tasks is Completed");
tokenSource2.Cancel();
tokenSource3.Cancel();
handler.Shutdown(SocketShutdown.Both);
handler.Close();
break; //breaking from polling loop to prepare for a new connection
}
}
} catch (SocketException se) {
Console.WriteLine(se.ToString());
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
listener.Dispose(); //disposing listener so that new one can be created
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static int Main(String[] args) {
SynchronousSocketListener synSocList = new SynchronousSocketListener();
var task_generateMsg = Task.Run(
(synSocList.threadForGeneratingMessages));
synSocList.StartListening();
return 0;
}
}
client's app structure is basically the same as server's with exception, that it is actively trying to connect to server, if connection has been disrupted:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class SynchronousSocketClient {
private Socket sender; //socket
private byte[] bytes; // Data buffer for incoming data.
private List < String > messagesToSend;
private Mutex messagesToSendMutex;
public SynchronousSocketClient() {
messagesToSendMutex = new Mutex();
try {
messagesToSendMutex.WaitOne();
messagesToSend = new List < String > ();
} finally {
messagesToSendMutex.ReleaseMutex();
}
bytes = new Byte[1024];
sender = null;
}
private void addMessageToQueue(string message) {
try {
messagesToSendMutex.WaitOne();
messagesToSend.Add(message);
} finally {
messagesToSendMutex.ReleaseMutex();
}
}
private string readMessageFromQueue() {
string ret = null;
try {
messagesToSendMutex.WaitOne();
if (messagesToSend.Count > 0)
ret = messagesToSend[0];
} finally {
messagesToSendMutex.ReleaseMutex();
}
return ret;
}
private void removeMessageFromQueue(string messageToRemove) {
string ret = null;
try {
messagesToSendMutex.WaitOne();
if (messagesToSend.Count > 0)
messagesToSend.Remove(messageToRemove);
} finally {
messagesToSendMutex.ReleaseMutex();
}
}
private void threadForGeneratingMessages() {
while (true) {
addMessageToQueue(Console.ReadLine());
}
}
private void sendingThread(CancellationToken ct) {
while (true) {
try {
if (ct.IsCancellationRequested) {
// Clean up here, then...
ct.ThrowIfCancellationRequested();
Console.WriteLine("Task sending is cancelled");
return;
}
} catch (System.OperationCanceledException ex) {
Console.WriteLine("System.OperationCanceledException");
return;
}
if (messagesToSend.Count <= 0) {
Console.WriteLine("No more messages to send");
Thread.Sleep(5000);
continue;
}
Console.WriteLine("Client is going to write some data for client");
//send pending messages to client
string dataToSendNow = messagesToSend[0];
byte[] msg = Encoding.ASCII.GetBytes(dataToSendNow + "<EOF>");
try {
// Send the data through the socket.
int bytesSent = sender.Send(msg);
messagesToSend.Remove(dataToSendNow);
Console.WriteLine("Client send data");
} catch (SocketException ex) {
Console.WriteLine(ex.ToString());
Console.WriteLine("returning from sendingThread sockEx");
return;
} catch (ObjectDisposedException ex) {
Console.WriteLine(ex.ToString());
//socketError = true;
Console.WriteLine("returning from sendingThread objDisEx");
return;
}
}
}
private void receivingThread(CancellationToken ct) {
while (true) {
try {
if (ct.IsCancellationRequested) {
// Clean up here, then...
ct.ThrowIfCancellationRequested();
Console.WriteLine("Task receiving is cancelled");
return;
}
} catch (System.OperationCanceledException ex) {
Console.WriteLine("System.OperationCanceledException");
return;
}
Console.WriteLine("Client is waiting for a new message to arrive: ");
try {
if (!sender.Connected) throw new SocketException();
//sender.Send(new byte[] { 0 });
int bytesRec = sender.Receive(bytes);
string receivedData = Encoding.ASCII.GetString(bytes, 0, bytesRec);
Console.WriteLine("Client has received message = {0}",
receivedData);
/*
//do some stuff with the message
.
.
.
*/
} catch (SocketException ex) {
Console.WriteLine(ex.ToString());
//socketError = true;
return;
} catch (ObjectDisposedException ex) {
Console.WriteLine(ex.ToString());
//socketError = true;
return;
}
}
}
private void sendingThread() {
while (true) {
Console.WriteLine("Write some data for server");
string line = Console.ReadLine();
byte[] msg = Encoding.ASCII.GetBytes(line + "<EOF>");
try {
// Send the data through the socket.
int bytesSent = sender.Send(msg);
Console.WriteLine("data are send");
// Receive the response from the remote device.
} catch (SocketException ex) {
Console.WriteLine(ex.ToString());
socketError = false;
return;
}
Thread.Sleep(100);
}
}
volatile private bool socketError = false;
private void receivingThread() {
while (true) {
Console.WriteLine("receiving:");
try {
if (!sender.Connected) throw new SocketException();
sender.Send(new byte[] {
0
});
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
} catch (SocketException ex) {
Console.WriteLine(ex.ToString());
socketError = true;
return;
}
}
}
public void StartClient() {
// Data buffer for incoming data.
while (true) {
// 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(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11100);
// Create a TCP/IP socket.
sender = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try {
sender.Connect(remoteEP);
Console.WriteLine("Client has made connection to the server");
/*
try
{
task_send.Wait();
}
catch (AggregateException ae)
{
Console.WriteLine(ae.ToString());
foreach (var ex in ae.InnerExceptions)
{
throw ex;
}
}
*/
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
//when new connection is made create new thread for sending data through socket
var task_send = Task.Run(() => {
sendingThread(ct);
}, tokenSource2.Token);
var tokenSource3 = new CancellationTokenSource();
CancellationToken ct3 = tokenSource3.Token;
//when new connection is made create new thread for receiving data through socket
var task = Task.Run(() => {
receivingThread(ct3);
}, tokenSource3.Token);
while (true) {
if (task.IsCompleted || task_send.IsCompleted) { //activelly oolling the field to find out, wether threads has been cancelled/returned
Console.WriteLine("some tasks is Completed");
tokenSource2.Cancel();
tokenSource3.Cancel();
sender.Shutdown(SocketShutdown.Both);
sender.Close();
break; //breaking from polling loop to prepare for a new connection
}
}
/*
var task_send = Task.Run(
(sendingThread));
var task = Task.Run(
(receivingThread));
*/
/*
try
{
task.Wait();
}
catch (AggregateException ae)
{
foreach (var ex in ae.InnerExceptions)
{
throw ex;
}
}*/
/*
bool task_receiving_res = false;
//int timeout = 60000;
Task<bool> task_receiving = new Task<bool>(() => receivingThread());
task_receiving.Start();
Console.WriteLine("here0");
if (await Task.WhenAny(task_receiving, Task.Delay(Timeout.Infinite)) == task_receiving)
{
Console.WriteLine("here-0");
// task completed within timeout
task_receiving_res = task_receiving.Result;
}
else
{
throw new TimeoutException();
}
Console.WriteLine("here");
bool task_sending_res = false;
//int timeout = 60000;
Task<bool> task_sending = new Task<bool>(() => sendingThread());
task_sending.Start();
if (await Task.WhenAny(task_sending, Task.Delay(Timeout.Infinite)) == task_sending)
{
// task completed within timeout
task_sending_res = task_sending.Result;
}
else
{
throw new TimeoutException();
}
*/
/*
Console.WriteLine("here1");
while (true) {
if (socketError) {
/*task.Dispose();
task_send.Dispose();
*/
/*
socketError = false;
throw new Exception("restart connection");
}
}*/
/*
while (true)
{
*/
/*Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());*/
/*
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
// 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));
*/
/*
bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
*/
/*
Thread.Sleep(5000);
}*/
// 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());
}
Thread.Sleep(5000);
}
}
public static int Main(String[] args) {
SynchronousSocketClient sc = new SynchronousSocketClient();
var task_generateMsg = Task.Run(
(sc.threadForGeneratingMessages));
sc.StartClient();
return 0;
}
}
How could these code be written do be more efficient? Is this safe, or are there any problems with these code (besides efficiency)?
Edit:
I have a problem with the code:
sometimes receivingThread is looping without halting at handler/sender.Receive() function, it seems to read 0 bytes even though other side does not send anything. How can this be corrected?
I use layered architecture. I create a server. I want the server to listen when the data arrives.
This is my server code in the DataAccess layer.
public class ServerDal : IServerDal
{
private TcpListener server;
private TcpClient client = new TcpClient();
public bool ServerStart(NetStatus netStatus)
{
bool status = false;
try
{
server = new TcpListener(IPAddress.Parse(netStatus.IPAddress), netStatus.Port);
server.Start();
status = true;
}
catch (SocketException ex)
{
Console.WriteLine("Starting Server Error..." + ex);
status = false;
}
return status;
}
public string ReceiveAndSend(NetStatus netStatus)
{
Byte[] bytes = new Byte[1024];
String data = null;
Mutex mutex = new Mutex(false, "TcpIpReceive");
mutex.WaitOne();
if (!client.Connected)
client = server.AcceptTcpClient();
try
{
NetworkStream stream = client.GetStream();
int i;
if ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: " + data);
}
}
catch (Exception ex)
{
Console.WriteLine("Connection Error..." + ex);
client.Close();
}
finally
{
mutex.ReleaseMutex();
}
return data;
}
}
I can listen to the client that first connects to the server. When the first connecting client disconnects, I can listen to the second connecting client.
I want to listen when both clients send data. How can I do that ? Thanks for your help.
I fixed the problem.
static List<TcpClient> tcpClients = new List<TcpClient>();
public void ReceiveMessage(NetStatus netStatus)
{
try {
TcpClient tcpClient = server.AcceptTcpClient();
tcpClients.Add(tcpClient);
Thread thread = new Thread(unused => ClientListener(tcpClient, netStatus));
thread.Start();
}
catch(Exception ex) {
Console.WriteLine("[ERROR...] Server Receive Error = {0} ", ex.Message);
}
}
public void ClientListener(object obj, NetStatus netStatus)
{
try
{
TcpClient tcpClient = (TcpClient)obj;
StreamReader reader = new StreamReader(tcpClient.GetStream());
while(true)
{
string message = null;
message = reader.ReadLine();
if(message!=null)
{
netStatus.IncommingMessage = message;
Console.WriteLine("[INFO....] Received Data = {0}", message);
}
}
}
catch(Exception ex)
{
Console.WriteLine("[ERROR....] ClientListener Error = {0}", ex.Message);
}
}
I am new to C#.
I am trying to establish a TCP communication using TLS over LAN but have no idea how to do it. I have done the same in java using following code :
SSLSocketFactory sslSocketFactory = Util.BuildSslSocketFactoryForLAN(getApplicationContext());
Socket tcpSocket = sslSocketFactory.createSocket("IP address", "port");
is = tcpSocket.getInputStream();
OutputStream os = tcpSocket.getOutputStream();
devicePairingReq = Util.hexStringToByteArray("9F" + data);
os.write(devicePairingReq);
os.flush();
while (true) {
tcpSocket.setSoTimeout(1000 * 90);
resp = new byte[15];
test = is.read(resp);
tcpSocket.close();
public static SSLSocketFactory BuildSslSocketFactoryForLAN(Context context) {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream is = context.getResources().getAssets().open("name.pem");
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
sslContext.init(null, tmf.getTrustManagers(), null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
return sslSocketFactory;
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
I am totally new to C# so have very little idea about it.
I am trying to sent a message to tcp server from mobile client over LAN.
I'm doing an application which require me as a client side to connect to a server and receive data from the server. I will need to do re-connection when the connection is disconnected. Below is my code:
public enum MySocketState
{
Disconnected = 0,
Connecting,
Connected
}
private Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private byte[] _recieveBuffer = new byte[128];
void DataProcess()
{
try
{
if (_serverSocket == null || sockState == MySocketState.Disconnected)
{
Console.WriteLine("Trying to connect...");
SetupServer();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private void SetupServer()
{
try
{
_serverSocket.Connect("192.168.1.11", 1000);
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
}
sockState = MySocketState.Connected;
Console.WriteLine("Server connected...");
_serverSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
private void ReceiveCallback(IAsyncResult AR)
{
try
{
if (_serverSocket == null)
_serverSocket = (Socket)AR.AsyncState;
int recieved = _serverSocket.EndReceive(AR);
if (recieved <= 0)
{
CloseSocket();
return;
}
byte[] recData = new byte[recieved];
Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved);
string strData = ASCIIEncoding.ASCII.GetString(recData);
Console.WriteLine(strData);
//Process the data stored in recData
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
CloseSocket();
}
finally
{
try
{
//Start receiving again
if (_serverSocket != null)
_serverSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
catch (Exception ex2)
{ }
}
}
public void CloseSocket()
{
try
{
if (_serverSocket != null)
{
if (_serverSocket.Connected)
_serverSocket.Shutdown(SocketShutdown.Both);
_serverSocket.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
_serverSocket = null;
sockState = MySocketState.Disconnected;
}
private void timer1_Tick(object sender, EventArgs e)
{
DataProcess();
}
I'm using a timer (timer1_tick) to always detect whether or not the server is connected.
But after it disconnected with the server, it cannot be reconnected back and below is the error message on line _serverSocket.Connect("192.168.1.11", 1000):
A first chance exception of type 'System.NullReferenceException' occurred in fform.exe
System.NullReferenceException: Object reference not set to an instance of an object.
at fform.Form1.SetupServer() in c:\Work\Project 2015\Form1.cs:line 143
at fform.Form1.DataProcess() in c:\Work\Project 2015\Form1.cs:line 79
Do you guys know how come it cannot be connect back?
Probably it's because you set _serverSocket to null after you CloseSocket() and did not create a new Socket instance when you try to reconnect.
public void CloseSocket()
{
...
_serverSocket = null;
...
}
Look at the line number in the error message
at fform.Form1.SetupServer() in c:\Work\Project 2015\Form1.cs:line
143 at fform.Form1.DataProcess() in c:\Work\Project
2015\Form1.cs:line 79
You should probably do the following when you reconnect:
private void SetupServer()
{
try
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Added
_serverSocket.Connect("192.168.1.11", 1000);
}
...
}
I'm writing a tcp server in c# and corresponding client in java. I'm testing the connection on localhost, and the client is able to connect to the server. However, when I'm sending messages, the client never receives them. Using the debugger I've verified that stream.Write(...) is executed. Any idea what the problem could be?
This is the c# server:
TcpClient client = (TcpClient)cl;
NetworkStream stream = client.GetStream();
byte[] msg = new byte[512];
int bytesRead;
while (running)
{
while (messages.getCount() > 0)
{
String msg = messages.Take();
if (cmd != null)
{
byte[] bytes = Encoding.UTF8.GetBytes(msg.ToCharArray());
try
{
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
}
catch (Exception e)
{
}
}
}
Thread.Sleep(1000);
}
And the Java client:
public void run()
{
try
{
socket = new Socket(address, port);
in = new BufferedReader( new InputStreamReader( socket.getInputStream() ));
out = new PrintWriter(socket.getOutputStream());
running = true;
}
catch (Exception e){
e.printStackTrace();
running = false;
}
String data;
while(running)
{
try
{
data = in.readLine();
if(data != null)
{
processData(data);
}
}
catch (IOException e)
{
e.printStackTrace();
running = false;
break;
}
}
try
{
socket.close();
socket = null;
}
catch (IOException e)
{
e.printStackTrace();
}
running = false;
}
You're using BufferedReader.readLine(). Are your message strings terminated by a CR, LF, or CR/LF?
readLine blocks until a line-terminating character is read.