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.
Related
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 trying to create an SSL HTTP client (to send data over TLS) with custom trust store and client store certificates. I was able to do this in Java via OKHTTP, but I am confused how I can do this in C#/.net
Here is OKHTTP approach I used:
byte[] trustStoreBytes = ...
byte[] clientCertBytes = ...
TrustManagerFactory trustManagerFactory = null;
try
{
trustManagerFactory = createTrustManagerFactory(trustStoreBytes, trustStorePass);
}
catch (Exception e)
{
Log.e(TAG, "Exception initializing TrustManagerFactory.", e);
}
if (trustManagerFactory == null)
{
Log.e(TAG, "TrustManagerFactory cannot be null.");
}
SSLContext sslContext = null;
try
{
sslContext = createSSLContext(clientCertBytes, clientCertPass, trustManagerFactory);
}
catch (Exception e)
{
Log.e(TAG, "Exception initializing SSLContext.", e);
}
if (sslContext == null)
{
Log.e(TAG, "SSLContext cannot be null.");
}
SSLSocketFactory sslSocketFactory = null;
X509TrustManager trustManager = null;
try
{
sslSocketFactory = sslContext.getSocketFactory();
trustManager = getX509TrustManager(trustManagerFactory);
Log.d(TAG, "newSecureWebSocketsClient: " + sslSocketFactory.getDefaultCipherSuites().toString());
}
catch (Exception e)
{
Log.e(TAG, "Unable to create ssl socket factory or trust manager.", e);
}
if (sslSocketFactory == null)
{
Log.e(TAG, "SSL Socket Factory cannot be null.");
}
if (trustManager == null)
{
Log.e(TAG, "Trust manager cannot be null");
}
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
clientBuilder.sslSocketFactory(sslSocketFactory, trustManager);
clientBuilder.retryOnConnectionFailure(true);
clientBuilder.hostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session)
{
Log.i(TAG, "Hostname: " + hostname);
Log.w(TAG, "Hostname verification is disabled. If you are using DNS," +
" this could introduce security risks for you.");
return true;
}
});
return clientBuilder.build();
Here is my initial attempt with System.Net.Http.HTTPClient
HttpClient client = new HttpClient();
WebRequestHandler handler = new WebRequestHandler();
X509Certificate2 cert = new X509Certificate2(clientBytes, "password");
handler.ClientCertificates.Add(cert);
handler.ClientCertificates.Add( ??? );
I could add a trust store certificate to the ClientCertificates but that seems wrong. What is the right approach here? Thanks!
I'm trying to create a TCP client on Android and a UWP server. Server should run on a Raspberry PI 2.
Client works with a synchronous server, but it doesn't work with this asynchronous server.
This is the Client
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity{
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText)findViewById(R.id.address); //
editTextPort = (EditText)findViewById(R.id.port);
buttonConnect = (Button)findViewById(R.id.connect);
buttonClear = (Button)findViewById(R.id.clear);
textResponse = (TextView)findViewById(R.id.response);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonClear.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
textResponse.setText("");
}});
}
OnClickListener buttonConnectOnClickListener =
new OnClickListener(){
String tMsg = "TEST";
#Override
public void onClick(View arg0) {
MyClientTask myClientTask = new MyClientTask(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()), tMsg);
myClientTask.execute();
}};
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
String msgToServer;
MyClientTask(String addr, int port, String msgTo){
dstAddress = addr;
dstPort = port;
msgToServer = msgTo;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
DataOutputStream dataOutputStream = null;
try {
socket = new Socket(dstAddress, dstPort);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
if(msgToServer != null){
dataOutputStream.writeBytes(msgToServer);
}
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice:
* inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
And this is the Server
private async void AvviaServer()
{
try
{
//Create a StreamSocketListener to start listening for TCP connections.
Windows.Networking.Sockets.StreamSocketListener socketListener = new Windows.Networking.Sockets.StreamSocketListener();
//Hook up an event handler to call when connections are received.
socketListener.ConnectionReceived += SocketListener_ConnectionReceived;
//Start listening for incoming TCP connections on the specified port. You can specify any port that's not currently in use.
await socketListener.BindServiceNameAsync("9999");
//TxtMex.Text = "PRONTO";
}
catch (Exception e)
{
TxtMex.Text = e.Message;
}
}
private async void SocketListener_ConnectionReceived(Windows.Networking.Sockets.StreamSocketListener sender, Windows.Networking.Sockets.StreamSocketListenerConnectionReceivedEventArgs args)
{
//Read line from the remote client.
Stream inStream = args.Socket.InputStream.AsStreamForRead();
StreamReader reader = new StreamReader(inStream);
request = await reader.ReadLineAsync();
//Send the line back to the remote client.
Stream outStream = args.Socket.OutputStream.AsStreamForWrite();
StreamWriter writer = new StreamWriter(outStream);
await writer.WriteLineAsync(request);
await writer.FlushAsync();
}
Thanks everybody
We cannot see what your client writes. But your server is expecting a line. It looks as if your client is not sending a line. Add a "\n" or "\r\n" to the message string to send a line.
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!
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.