I want to make a TCP socket connection.
my server code in java.
// File Name GreetingServer.java
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread {
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run() {
while(true) {
try {
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
+ "\nGoodbye!");
server.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String [] args) {
int port = Integer.parseInt(args[0]);
try {
Thread t = new GreetingServer(port);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I want to make a client in react-native .
Import the library:
import TcpSocket from 'react-native-tcp-socket';
// const net = require('react-native-tcp-socket');
Client
// Create socket
const client = TcpSocket.createConnection(options, () => {
// Write on the socket
client.write('Hello server!');
// Close socket
client.destroy();
});
client.on('data', function(data) {
console.log('message was received', data);
});
client.on('error', function(error) {
console.log(error);
});
client.on('close', function(){
console.log('Connection closed!');
});
I referred to the above code here.
But, I need more information.
Where can I provide the server's IP address in client side?
I need a small example for TCP client in react-native.
Seems you need to specify IP in the option object in the host field, as described in the react-native-tcp-socket doc.
host - Host the socket should connect to. IP address in IPv4 format or 'localhost'. Default: 'localhost'.
For example:
const options = {
port: 8443,
host: "example.com", //give your IP address
tls: true,
};
// Create socket
const client = TcpSocket.createConnection(options, () => {
// Write on the socket
client.write('Hello server!');
// Close socket
client.destroy();
});
Related
I am trying to setup a connection listener for my redisson client. It is not getting invoked on both connect/disconnect.
Tried the code mentioned on the redisson github which is as per below:
public void createRedisClient(Handler<AsyncResult<Redis>> handler) {
ConfigRetriever configRetriever = UDSFBootStrapper.getInstance().getConfigRetriever();
configRetriever.getConfig(
config -> {
String redisUrl = config.result().getString("redisip");
redisUrl += ":";
redisUrl += config.result().getInteger("redisport");
Config rconfig = new Config();
rconfig.setTransportMode(TransportMode.EPOLL);
rconfig.useClusterServers()
.addNodeAddress(UdsfConstants.REDIS_CONNECTION_PREFIX + redisUrl);
rclient = Redisson.create(rconfig);
rclient.getNodesGroup().addConnectionListener(new ConnectionListener() {
//#Override
public void onConnect(InetSocketAddress inetSocketAddress) {
logger.info("Redis server connected");
}
//#Override
public void onDisconnect(InetSocketAddress inetSocketAddress) {
logger.info("Redis server disconnected");
}
});
});
}
I'm working with the Renci SSH.Net library on a WPF application and I'm having an issue with using the SFTP client. When the user tries to connect to download some files from the SFTP server he gets the message shown below:
Server response does not contain ssh protocol identification
It doesn't appear to be something specific with the server as I'm able to connect and download the files just fine on my development desktop and a secondary laptop. The same application is able to connect over SSH and run commands without issue, it's just the SFTP connection that appears to be the problem. I'm looking for a little guidance as to where to begin troubleshooting this.
Code for SFTP shown below:
void DownloadPlogs()
{
try
{
SftpClient SFTP;
if (GV.UseCustomPort && GV.CustomPort > 0 && GV.CustomPort < 65535)
{
SFTP = new SftpClient(GV.IpAddress, GV.CustomPort, GV.Username, GV.Password);
}
else
{
SFTP = new SftpClient(GV.IpAddress, 22, GV.Username, "");
}
SFTP.Connect();
DownloadDirectory(SFTP, "/PLOG", Directory.GetCurrentDirectory() + #"\PLOG");
ZipFile.CreateFromDirectory("PLOG", String.Format("{0} - {1} PLOGS.zip", GV.IpAddress, DateTime.Now.ToString("yyyyMMddHHmmss")));
Directory.Delete(Directory.GetCurrentDirectory() + #"\PLOG", true);
SFTP.Disconnect();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error Getting PLOGS");
}
}
void DownloadDirectory(SftpClient Client, string Source, string Destination)
{
var Files = Client.ListDirectory(Source);
foreach (var File in Files)
{
if (!File.IsDirectory && !File.IsSymbolicLink)
{
DownloadFile(Client, File, Destination);
}
else if (File.IsSymbolicLink)
{
//Ignore
}
else if (File.Name != "." && File.Name != "..")
{
var Dir = Directory.CreateDirectory(System.IO.Path.Combine(Destination, File.Name));
DownloadDirectory(Client, File.FullName, Dir.FullName);
}
}
}
void DownloadFile(SftpClient Client, Renci.SshNet.Sftp.SftpFile File, string Directory)
{
using (Stream FileStream = System.IO.File.OpenWrite(System.IO.Path.Combine(Directory, File.Name)))
{
Client.DownloadFile(File.FullName, FileStream);
}
}
Code for SSH below:
public SshConnection(string Host, int Port, string Username, string Password)
{
myClient = new SshClient(Host, Port, Username, Password);
myClient.KeepAliveInterval = new TimeSpan(0, 0, 5);
myClient.HostKeyReceived += myClient_HostKeyReceived;
myClient.ErrorOccurred += myClient_ErrorOccurred;
}
void myClient_ErrorOccurred(object sender, Renci.SshNet.Common.ExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "SSH Error Occurred");
}
void myClient_HostKeyReceived(object sender, Renci.SshNet.Common.HostKeyEventArgs e)
{
e.CanTrust = true;
}
public async void Connect()
{
Task T = new Task(() =>
{
try
{
myClient.Connect();
}
catch (System.Net.Sockets.SocketException)
{
MessageBox.Show("Invalid IP Address or Hostname", "SSH Connection Error");
}
catch (Renci.SshNet.Common.SshAuthenticationException ex)
{
MessageBox.Show(ex.Message, "SSH Authentication Error");
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace, ex.Message);
MessageBox.Show(ex.GetType().ToString());
OnConnection(this, new ConnectEventArgs(myClient.IsConnected));
}
});
T.Start();
await T;
if (T.IsCompleted)
{
OnConnection(this, new ConnectEventArgs(myClient.IsConnected));
}
}
public void Disconnect()
{
try
{
myClient.Disconnect();
OnConnection(this, new ConnectEventArgs(myClient.IsConnected));
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace, ex.Message);
}
}
public void SendData(string Data)
{
try
{
if (Data.EndsWith("\r\n"))
{
RunCommandAsync(Data, SshCommandRx);
}
else
{
RunCommandAsync(String.Format("{0}\r\n",Data), SshCommandRx);
}
//SshCommand Command = myClient.RunCommand(Data);
//OnDataReceived(this, new DataEventArgs(Command.Result));
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace, ex.Message);
}
}
private async void RunCommandAsync(String Data, SshCommandCallback Callback)
{
Task<SshCommand> T = new Task<SshCommand>(() =>
{
try
{
SshCommand Command = myClient.RunCommand(Data);
return Command;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.GetType().ToString());
return null;
}
});
T.Start();
await T;
if (T.IsCompleted)
{
Callback(this, T.Result);
}
}
private void SshCommandRx(SshConnection C, SshCommand Command)
{
if (Command != null)
{
string Rx = Command.Result;
//if (Rx.StartsWith(Command.CommandText))
//{
// Rx = Rx.Remove(0, Command.CommandText.Length);
//}
while (Rx.EndsWith("\r\n\r\n") == false)
{
Rx += "\r\n";
}
OnDataReceived(this, new DataEventArgs(Rx));
}
}
I solve it for my self only with connections retrying attempts. Didn't find what exactly the issue is, but have this connection issue many times.
Example:
int attempts = 0;
do
{
try
{
client.Connect();
}
catch (Renci.SshNet.Common.SshConnectionException e)
{
attempts++;
}
} while (attempts < _connectiontRetryAttempts && !client.IsConnected);
I experienced the same odd error message when attempting to connect to a SFTP server while using the SSH.NET library in a program on the server. The problem did not appear while testing from my development machine.
The solution was to have our server team add the IP address of the server into the hosts.allow file on the SFTP Linux server.
I want to write an UDP Netty Server/Client with SSL . I did it in the way similar to TCP Netty Server/Client which worked well. But I meet an exception:
javax.net.ssl.SSLException:Received close_notify during handskake,close channel...
My netty is 3.x , SSL configure works well . Here is some code of my Udp Server and Client. Server:
serverBootstrap = new ConnectionlessBootstrap(
new NioDatagramChannelFactory(Executors.newCachedThreadPool(),maxThreads));
serverBootstrap.setOption("receiveBufferSizePredictorFactory",
new FixedReceiveBufferSizePredictorFactory(8192));
ChannelPipelineFactory fac = null;
try {
ServiceDecoder serviceProcessor = (ServiceDecoder)Class.forName(serviceDecoderName).newInstance();
Class<? extends ChannelPipelineFactory> clazz = (Class<? extends ChannelPipelineFactory>) Class
.forName(msgFactoryName);
Constructor ctor = clazz.getConstructor(ChannelProcessor.class,
ChannelGroup.class, CounterGroup.class, CounterGroupExt.class, String.class,ServiceDecoder.class,
String.class, Integer.class, String.class, String.class, Boolean.class,Integer.class,Boolean.class,Boolean.class,Context.class);
logger.info("Using channel processor:{}", getChannelProcessor().getClass().getName());
fac = (ChannelPipelineFactory) ctor.newInstance(
getChannelProcessor(), allChannels, counterGroup, counterGroupExt, "udp", serviceProcessor,
messageHandlerName, maxMsgLength, topic, attr, filterEmptyMsg, maxConnections, isCompressed,enableSsl,context);
} catch (Exception e) {
logger.error(
"Simple Udp Source start error, fail to construct ChannelPipelineFactory with name {}, ex {}",
msgFactoryName, e);
stop();
throw new FlumeException(e.getMessage());
}
serverBootstrap.setPipelineFactory(fac);
try {
if (host == null) {
nettyChannel = serverBootstrap
.bind(new InetSocketAddress(port));
} else {
nettyChannel = serverBootstrap.bind(new InetSocketAddress(host,
port));
}
Pipeline in Server:
if(enableSsl) {
cp.addLast("ssl", sslInit());
}
if (processor != null) {
try {
Class<? extends SimpleChannelHandler> clazz = (Class<? extends SimpleChannelHandler>) Class
.forName(messageHandlerName);
Constructor<?> ctor = clazz.getConstructor(
ChannelProcessor.class, ServiceDecoder.class, ChannelGroup.class,
CounterGroup.class, CounterGroupExt.class, String.class, String.class,
Boolean.class, Integer.class, Integer.class, Boolean.class);
SimpleChannelHandler messageHandler = (SimpleChannelHandler) ctor
.newInstance(processor, serviceProcessor, allChannels,
counterGroup, counterGroupExt, topic, attr,
filterEmptyMsg, maxMsgLength, maxConnections, isCompressed);
cp.addLast("messageHandler", messageHandler);
} catch (Exception e) {
e.printStackTrace();
}
}
if (this.protocolType.equalsIgnoreCase(ConfigConstants.UDP_PROTOCOL)) {
cp.addLast("execution", executionHandler);
}
client:
private ConnectionlessBootstrap clientBootstrap;
clientBootstrap = new ConnectionlessBootstrap(
new NioDatagramChannelFactory(Executors.newCachedThreadPool()));
clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
#Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("sslHandler", sslInit());
pipeline.addLast("orderHandler",new ExecutionHandler(
new OrderedMemoryAwareThreadPoolExecutor(cores * 2,
1024 * 1024, 1024 * 1024)));
return pipeline;
}
});
Two function to send message in the client:
public void sendMessage(byte[] data) {
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(data);
sendMessage(buffer);
}
public void sendMessage(ChannelBuffer buffer) {
Random random = new Random();
Channel channel = channelList.get(random.nextInt(channelList.size()));
if(!channel.isConnected()){
channel.close();
ChannelFuture cf = clientBootstrap
.connect(new InetSocketAddress(ip, port));
if(cf.awaitUninterruptibly(3000, TimeUnit.MILLISECONDS)){
channel = cf.getChannel();
}else {
channelList.remove(channel);
return;
}
}
ChannelFuture future = channel.write(buffer);
if(!future.awaitUninterruptibly(3, TimeUnit.SECONDS)){
logger.warn("send failed!{}",future.getCause());
}else {
sendCnt.incrementAndGet();
}
}
I suspect whether UDP Netty Server/Client support SSL. Any tips are appreciated.
UDP does not guarantee the order of packets, as opposed to TCP, since there is no session. Thus, during the SSL negotiation, there could be an issue, depending on the order of the UDP packets.
According to what I read, you might have a look to DTLS which suppose to add a sort of order control in UDP packets, but lot of SSL libraries do not support it.
Since Netty only implements TLS, it may not work with UDP.
I am trying to create a mule flow with a TCP inbound endpoint which is a TCP server that listens to a port. When a successful client connection is identified, before receiving any request from the client, I need to write a message into the socket (which lets the client know that I am listening), only after which the client sends me further requests. This is how I do it with a sample java program :
import java.net.*;
import java.io.*;
public class TCPServer
{
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4445);
}
catch (IOException e)
{
System.err.println("Could not listen on port: 4445.");
System.exit(1);
}
Socket clientSocket = null;
System.out.println ("Waiting for connection.....");
try {
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
System.out.println ("Connection successful");
System.out.println ("Sending output message - .....");
//Sending a message to the client to indicate that the server is active
PrintStream pingStream = new PrintStream(clientSocket.getOutputStream());
pingStream.print("Server listening");
pingStream.flush();
//Now start listening for messages
System.out.println ("Waiting for incoming message - .....");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
{
System.out.println ("Server: " + inputLine);
out.println(inputLine);
if (inputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
I have tried to use Mule's TCP inbound endpoint as a server, but I am not able to see how I can identify a successful connection from the client, inorder to trigger the outbound message. The flow gets triggered only when a message is sent across from the client. Is there a way I can extend the functionality of the Mule TCP connector and have a listener which could do the above requirement?
Based on the answer provided, this is how I implemented this -
public class TCPMuleOut extends TcpMessageReceiver {
boolean InitConnection = false;
Socket clientSocket = null;
public TCPMuleOut(Connector connector, FlowConstruct flowConstruct,
InboundEndpoint endpoint) throws CreateException {
super(connector, flowConstruct, endpoint);
}
protected Work createWork(Socket socket) throws IOException {
return new MyTcpWorker(socket, this);
}
protected class MyTcpWorker extends TcpMessageReceiver.TcpWorker {
public MyTcpWorker(Socket socket, AbstractMessageReceiver receiver)
throws IOException {
super(socket, receiver);
// TODO Auto-generated constructor stub
}
#Override
protected Object getNextMessage(Object resource) throws Exception {
if (InitConnection == false) {
clientSocket = this.socket;
logger.debug("Sending logon message");
PrintStream pingStream = new PrintStream(
clientSocket.getOutputStream());
pingStream.print("Log on message");
pingStream.flush();
InitConnection = true;
}
long keepAliveTimeout = ((TcpConnector) connector)
.getKeepAliveTimeout();
Object readMsg = null;
try {
// Create a monitor if expiry was set
if (keepAliveTimeout > 0) {
((TcpConnector) connector).getKeepAliveMonitor()
.addExpirable(keepAliveTimeout,
TimeUnit.MILLISECONDS, this);
}
readMsg = protocol.read(dataIn);
// There was some action so we can clear the monitor
((TcpConnector) connector).getKeepAliveMonitor()
.removeExpirable(this);
if (dataIn.isStreaming()) {
}
return readMsg;
} catch (SocketTimeoutException e) {
((TcpConnector) connector).getKeepAliveMonitor()
.removeExpirable(this);
System.out.println("Socket timeout");
} finally {
if (readMsg == null) {
// Protocols can return a null object, which means we're
// done
// reading messages for now and can mark the stream for
// closing later.
// Also, exceptions can be thrown, in which case we're done
// reading.
dataIn.close();
InitConnection = false;
logger.debug("Client closed");
}
}
return null;
}
}
}
And the TCP connector is as below:
<tcp:connector name="TCP" doc:name="TCP connector"
clientSoTimeout="100000" receiveBacklog="0" receiveBufferSize="0"
sendBufferSize="0" serverSoTimeout="100000" socketSoLinger="0"
validateConnections="true" keepAlive="true">
<receiver-threading-profile
maxThreadsActive="5" maxThreadsIdle="5" />
<reconnect-forever />
<service-overrides messageReceiver="TCPMuleOut" />
<tcp:direct-protocol payloadOnly="true" />
</tcp:connector>
What you're trying to do is a little difficult to accomplish but not impossible. The messages are received by the org.mule.transport.tcp.TcpMessageReceiver class, and this class always consumes the data in the input stream to create the message that injects in the flow.
However, you could extend that receiver and instruct the TCP module to use yours by adding a service-overrides tag in your flow's tcp connector (documented here) and replacing the messageReceiver element.
In your extended receiver you should change the TcpWorker.getNextMessage method in order to send the ack message before read from the input stream.
HTH, Marcos.
I am trying to create a server using SSL but I keep getting the following error:
"Server aborted:javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled."
I am not sure if I am creating the certificates correctly. Here is my code.
I am converting an old TCP Server to an SSL Server
// SSL Server
import java.net.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocketFactory;
public class SSL_Server {
public static void main(String[] args) {
int port = 2018;
ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
ServerSocket ssocket = null;
System.out.println("SSL_Server started");
System.setProperty("javax.net.ssl.keyStore","mySrvKeystore");
System.setProperty("javax.net.ssl.keyStorePassword","123456");
final ExecutorService threadPool = Executors.newCachedThreadPool();
try {
ssocket = ssocketFactory.createServerSocket(port);
InetAddress myIP =InetAddress.getLocalHost();
System.out.println(myIP.getHostAddress());
while(true){
Socket aClient = ssocket.accept();
//create a new thread for every client
threadPool.submit(new SSL_ClientHandler(aClient));
}
}
catch(Exception e) {
System.err.println("Server aborted:" + e);
} finally {
try{
ssocket.close();
} catch (Exception e){
System.err.println("could not close connection properly" + e);
}
}
System.out.println("connection was closed successfully");
}
}
System.setProperty("javax.net.ssl. keyStore","mySrvKeystore"); System.setProperty("javax.net.ssl. keyStorePassword","123456");
ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
ServerSocket ssocket = null;
System.out.println("SSL_Server started");
You should set the properties that configure the default SSLContext (and thus the default SSLServerSocketFactory) before getting it, since it will configure it then.
System.setProperty("javax.net.ssl.keyStore","mySrvKeystore");
System.setProperty("javax.net.ssl.keyStorePassword","123456");
ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
ServerSocket ssocket = null;
System.out.println("SSL_Server started");