I am trying to use BluetoothConnectionService written by Mitch Tabian to connect to a Microchip BM77 dual mode module. I am trying to connect with transparent BT.
From the logcat it seems that it can not connect to the UUID and then closes socket.
Is this BM77 device not able to connect using RFcommsocket? Does it require a different UUID?
package com.example.user.bluetooth_communication;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.UUID;
/**
* Created by User on 12/21/2016.
*/
public class BluetoothConnectionService {
private static final String TAG = "BluetoothConnectionServ";
private static final String appName = "MYAPP";
private static final UUID MY_UUID_INSECURE =
UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");
private final BluetoothAdapter mBluetoothAdapter;
Context mContext;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private BluetoothDevice mmDevice;
private UUID deviceUUID;
ProgressDialog mProgressDialog;
private ConnectedThread mConnectedThread;
public BluetoothConnectionService(Context context) {
mContext = context;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
start();
}
/**
* This thread runs while listening for incoming connections. It behaves
* like a server-side client. It runs until a connection is accepted
* (or until cancelled).
*/
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
public AcceptThread(){
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try{
tmp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(appName, MY_UUID_INSECURE);
Log.d(TAG, "AcceptThread: Setting up Server using: " + MY_UUID_INSECURE);
}catch (IOException e){
Log.e(TAG, "AcceptThread: IOException: " + e.getMessage() );
}
mmServerSocket = tmp;
}
public void run(){
Log.d(TAG, "run: AcceptThread Running.");
BluetoothSocket socket = null;
try{
// This is a blocking call and will only return on a
// successful connection or an exception
Log.d(TAG, "run: RFCOM server socket start.....");
socket = mmServerSocket.accept();
Log.d(TAG, "run: RFCOM server socket accepted connection.");
}catch (IOException e){
Log.e(TAG, "AcceptThread: IOException: " + e.getMessage() );
}
//talk about this is in the 3rd
if(socket != null){
connected(socket,mmDevice);
}
Log.i(TAG, "END mAcceptThread ");
}
public void cancel() {
Log.d(TAG, "cancel: Canceling AcceptThread.");
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "cancel: Close of AcceptThread ServerSocket failed. " + e.getMessage() );
}
}
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
private class ConnectThread extends Thread {
private BluetoothSocket mmSocket;
public ConnectThread(BluetoothDevice device, UUID uuid) {
Log.d(TAG, "ConnectThread: started.");
mmDevice = device;
deviceUUID = uuid;
}
public void run(){
BluetoothSocket tmp = null;
Log.i(TAG, "RUN mConnectThread ");
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
Log.d(TAG, "ConnectThread: Trying to create InsecureRfcommSocket using UUID: "
+MY_UUID_INSECURE );
tmp = mmDevice.createRfcommSocketToServiceRecord(deviceUUID);
} catch (IOException e) {
Log.e(TAG, "ConnectThread: Could not create InsecureRfcommSocket " + e.getMessage());
}
mmSocket = tmp;
// Always cancel discovery because it will slow down a connection
mBluetoothAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
Log.d(TAG, "run: ConnectThread connected.");
} catch (IOException e) {
// Close the socket
try {
mmSocket.close();
Log.d(TAG, "run: Closed Socket.");
} catch (IOException e1) {
Log.e(TAG, "mConnectThread: run: Unable to close connection in socket " + e1.getMessage());
}
Log.d(TAG, "run: ConnectThread: Could not connect to UUID: " + MY_UUID_INSECURE );
}
//will talk about this in the 3rd video
connected(mmSocket,mmDevice);
}
public void cancel() {
try {
Log.d(TAG, "cancel: Closing Client Socket.");
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "cancel: close() of mmSocket in Connectthread failed. " + e.getMessage());
}
}
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume()
*/
public synchronized void start() {
Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = new AcceptThread();
mInsecureAcceptThread.start();
}
}
/**
AcceptThread starts and sits waiting for a connection.
Then ConnectThread starts and attempts to make a connection with the other devices AcceptThread.
**/
public void startClient(BluetoothDevice device,UUID uuid){
Log.d(TAG, "startClient: Started.");
//initprogress dialog
mProgressDialog = ProgressDialog.show(mContext,"Connecting Bluetooth"
,"Please Wait...",true);
mConnectThread = new ConnectThread(device, uuid);
mConnectThread.start();
}
/**
Finally the ConnectedThread which is responsible for maintaining the BTConnection, Sending the data, and
receiving incoming data through input/output streams respectively.
**/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "ConnectedThread: Starting.");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
//dismiss the progressdialog when connection is established
try{
mProgressDialog.dismiss();
}catch (NullPointerException e){
e.printStackTrace();
}
try {
tmpIn = mmSocket.getInputStream();
tmpOut = mmSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run(){
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
// Read from the InputStream
try {
bytes = mmInStream.read(buffer);
String incomingMessage = new String(buffer, 0, bytes);
Log.d(TAG, "InputStream: " + incomingMessage);
} catch (IOException e) {
Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
break;
}
}
}
//Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
String text = new String(bytes, Charset.defaultCharset());
Log.d(TAG, "write: Writing to outputstream: " + text);
try {
mmOutStream.write(bytes);
} catch (IOException e) {
Log.e(TAG, "write: Error writing to output stream. " + e.getMessage() );
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {
Log.d(TAG, "connected: Starting.");
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
/**
* Write to the ConnectedThread in an unsynchronized manner
*
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
Log.d(TAG, "write: Write Called.");
//perform the write
mConnectedThread.write(out);
}
}
D/ViewRootImpl#21bc2e2[MainActivity]: ViewPostIme pointer 0
D/ViewRootImpl#21bc2e2[MainActivity]: ViewPostIme pointer 1
D/AbsListView: onTouchUp() mTouchMode : 0
D/BluetoothAdapter: cancelDiscovery
D/BluetoothAdapter: cancelDiscovery = true
D/MainActivity: onItemClick: You Clicked on a device.
D/MainActivity: onItemClick: deviceName = Dual-SPP
onItemClick: deviceAddress = 34:81:F4:40:0F:2A
Trying to pair with Dual-SPP
I/BluetoothDevice: createBond() for device 40:0 called by pid: 27565 tid: 27565
D/BluetoothConnectionServ: start
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
D/BluetoothConnectionServ: AcceptThread: Setting up Server using: 8ce255c0-200a-11e0-ac64-0800200c9a66
D/BluetoothConnectionServ: run: AcceptThread Running.
run: RFCOM server socket start.....
D/ViewRootImpl#21bc2e2[MainActivity]: ViewPostIme pointer 0
D/ViewRootImpl#21bc2e2[MainActivity]: ViewPostIme pointer 1
D/MainActivity: startBTConnection: Initializing RFCOM Bluetooth Connection.
D/BluetoothConnectionServ: startClient: Started.
D/ScrollView: initGoToTop
D/ScrollView: initGoToTop
D/ViewRootImpl#fcf1c11[Connecting Bluetooth]: setView = DecorView#be25176[Connecting Bluetooth] TM=true MM=false
D/BluetoothConnectionServ: ConnectThread: started.
I/BluetoothConnectionServ: RUN mConnectThread
D/BluetoothConnectionServ: ConnectThread: Trying to create InsecureRfcommSocket using UUID: 8ce255c0-200a-11e0-ac64-0800200c9a66
D/ViewRootImpl#fcf1c11[Connecting Bluetooth]: dispatchAttachedToWindow
D/BluetoothAdapter: cancelDiscovery
D/BluetoothAdapter: cancelDiscovery = true
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0
D/ViewRootImpl#fcf1c11[Connecting Bluetooth]: Relayout returned: old=[0,0][0,0] new=[23,790][1057,1349] result=0x7 surface={valid=true 524643803136} changed=true
D/OpenGLRenderer: eglCreateWindowSurface = 0x7a27b171e0
D/ViewRootImpl#fcf1c11[Connecting Bluetooth]: MSG_WINDOW_FOCUS_CHANGED 1
D/ViewRootImpl#fcf1c11[Connecting Bluetooth]: MSG_RESIZED_REPORT: frame=Rect(23, 790 - 1057, 1349) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/ViewRootImpl#21bc2e2[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 0
D/BluetoothSocket: close() this: android.bluetooth.BluetoothSocket#3daba6f, channel: -1, mSocketIS: android.net.LocalSocketImpl$SocketInputStream#9c9637c, mSocketOS: android.net.LocalSocketImpl$SocketOutputStream#4f75405mSocket: android.net.LocalSocket#9c67c5a impl:android.net.LocalSocketImpl#b028e8b fd:java.io.FileDescriptor#2073b68, mSocketState: INIT
D/BluetoothConnectionServ: run: Closed Socket.
D/BluetoothConnectionServ: run: ConnectThread: Could not connect to UUID: 8ce255c0-200a-11e0-ac64-0800200c9a66
connected: Starting.
ConnectedThread: Starting.
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
D/OpenGLRenderer: eglDestroySurface = 0x7a27b171e0
D/ViewRootImpl#fcf1c11[Connecting Bluetooth]: dispatchDetachedFromWindow
D/InputEventReceiver: channel '48033aa Connecting Bluetooth (client)' ~ Disposing input event receiver.
D/InputEventReceiver: channel '48033aa Connecting Bluetooth (client)' ~NativeInputEventReceiver.
D/ViewRootImpl#21bc2e2[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1
E/ViewRootImpl: sendUserActionEvent() returned.
E/BluetoothConnectionServ: write: Error reading Input Stream. socket closed
Related
I'm developing a packet sniffer program that captures the packets going through a system using protocols(TCP,UDP,HTTP). The packet sniffer program will run on a system and captures the packets on another system using the other system's ip address. I'm successfully capturing the packets on my own system but I want to capture the packets on another system. Can someone help me with this issue.??
package packetsniffer;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import org.pcap4j.core.BpfProgram.BpfCompileMode;
import org.pcap4j.core.NotOpenException;
import org.pcap4j.core.PacketListener;
import org.pcap4j.core.PcapHandle;
import org.pcap4j.core.PcapNativeException;
import org.pcap4j.core.PcapNetworkInterface;
import org.pcap4j.core.PcapNetworkInterface.PromiscuousMode;
import org.pcap4j.core.PcapStat;
import org.pcap4j.packet.namednumber.IpNumber;
import org.pcap4j.packet.namednumber.TcpPort;
import org.pcap4j.packet.namednumber.UdpPort;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.IpV4Packet;
import org.pcap4j.packet.IpPacket;
import org.pcap4j.packet.TcpPacket;
import org.pcap4j.packet.UdpPacket;
import org.pcap4j.util.NifSelector;
import com.sun.jna.Platform;
import java.net.Inet4Address;
#SuppressWarnings("javadoc")
public class PacketSniffer {
private static final String COUNT_KEY
= PacketSniffer.class.getName() + ".count";
private static final int COUNT
= Integer.getInteger(COUNT_KEY, -1); // -1 -> loop infinite
private static final String READ_TIMEOUT_KEY
= PacketSniffer.class.getName() + ".readTimeout";
private static final int READ_TIMEOUT
= Integer.getInteger(READ_TIMEOUT_KEY, 100); // [ms]
private static final String SNAPLEN_KEY
= PacketSniffer.class.getName() + ".snaplen";
private static final int SNAPLEN
= Integer.getInteger(SNAPLEN_KEY, 65536); // [bytes]
// defines the header
private final String[] header = {"S. No.", "Timestamp",
"Source IP", "Destination IP","Src Port","Dst
Port","Protocol","Packet Length (Byte)","Info"};
private PcapNetworkInterface nif=null;
PcapHandle handle=null;
int pktCount = 0;
PacketTable packetTable=null;
int captureTime = 60; //seconds
Timer timer = new Timer();
private PacketSniffer(PcapNetworkInterface nif) {
this.nif = nif;
displayTable();
}
PacketListener listener
= new PacketListener() {
#Override
public void gotPacket(Packet packet) {
//System.out.println(handle.getTimestamp());
//System.out.println(packet);
printPacket(packet, handle.getTimestamp().toString());
}
};
//Packet count increment
synchronized private void incrementCount(){
pktCount++;
}
//get the packet count
synchronized private int getPacketCount(){
return pktCount;
}
//print the packet details
public void printPacket(Packet packet, String timestamp){
String srcIp, dstIp;
int srcPort=0, dstPort=0;
String info="";
//do nothing if not an IP packet
if (!packet.contains(IpPacket.class)) {
return;
}
//get the IP packet class
IpPacket ipPacket = packet.get(IpPacket.class);
srcIp = ipPacket.getHeader().getSrcAddr().getHostAddress().toString();
dstIp = ipPacket.getHeader().getDstAddr().getHostAddress().toString();
//int srcPort = ipv4packet.getHeader().
//}
String proto= ipPacket.getHeader().getProtocol().name();
if (proto.equals("TCP") ){
TcpPacket tcpPkt = packet.get(TcpPacket.class);
srcPort = tcpPkt.getHeader().getSrcPort().valueAsInt();
dstPort = tcpPkt.getHeader().getDstPort().valueAsInt();
}else if (proto.equals("UDP") ){
UdpPacket udpPkt = packet.get(UdpPacket.class);
srcPort = udpPkt.getHeader().getSrcPort().valueAsInt();
dstPort = udpPkt.getHeader().getDstPort().valueAsInt();
}else{
return;
}
//find if its HTTP packet
if (srcPort == 80 || srcPort == 8080 || dstPort == 80 || dstPort == 8080 ){
proto = "HTTP";
}else if(srcPort == 443 || dstPort == 443 ){
proto = "HTTPS";
}
int len = packet.length();
//print the header
if(getPacketCount()==0){
System.out.print("\n|---------------------------------------------------------------------------|");
System.out.print("\n|S.N.|Timestamp|Source IP|Destination IP|Src Port|Dst Port|Proto|Len|Info|");
}
//increment the count
incrementCount();
//print the details of packet
System.out.print("\n| "+getPacketCount()+" |"+timestamp+"|");
System.out.print(srcIp+"|"+dstIp+"| ");
System.out.print(srcPort+" | "+dstPort+" |"+proto+"|"+len+"|");
packetTable.model.add(String.valueOf(getPacketCount()),timestamp,srcIp,
dstIp, String.valueOf(srcPort),String.valueOf(dstPort),String.valueOf(proto),String.valueOf(len),info);
}
//Print Final stats
void printStat(){
PcapStat ps;
try {
ps = handle.getStats();
System.out.println("Packets Received: " + ps.getNumPacketsReceived());
System.out.println("Packets Dropped: " + ps.getNumPacketsDropped());
System.out.println("Packets Dropped By Intf: " + ps.getNumPacketsDroppedByIf());
if (Platform.isWindows()) {
System.out.println("Packets Captured: " + ps.getNumPacketsCaptured());
}
} catch (PcapNativeException | NotOpenException e) {
// Auto-generated catch block
e.printStackTrace();
}
}
//start capturing the packets
void startSniffing(){
try{
handle = nif.openLive(SNAPLEN, PromiscuousMode.PROMISCUOUS, READ_TIMEOUT);
System.out.println("\nRunning for time:"+captureTime+"seconds");
startTimer();
handle.loop(COUNT, listener);
} catch(PcapNativeException e){
e.printStackTrace();
}
catch (InterruptedException e) {
//e.printStackTrace();
}
catch (NotOpenException e) {
e.printStackTrace();
}
finally{
printStat();
handle.close();
timer.cancel();
}
}
//stop capturing the packets
void stopSniffing(){
System.out.println("\nStopping Sniffing...\n");
try {
handle.breakLoop();
} catch (NotOpenException e) {
// Auto-generated catch block
e.printStackTrace();
}
}
//Display the Packet Table GUI
void displayTable(){
// defines rows and column of the JTable
String[][] rowAndColumn = {
};
packetTable = new PacketTable(rowAndColumn, header);
}
//set the capture time
void setTime(int t){
captureTime = t > 0 ? t : 60;
}
//Start timer
void startTimer(){
timer.schedule(new TimerTask() {
#Override
public void run() {
stopSniffing();
}
}, captureTime*1000);
}
public static void main(String[] args) throws PcapNativeException, NotOpenException {
PcapNetworkInterface nif;
try {
nif = new NifSelector().selectNetworkInterface();
} catch (IOException e) {
e.printStackTrace();
return;
}
if (nif == null) {
return;
}
System.out.println(nif.getName() + "(" + nif.getDescription() + ") Selected!");
PacketSniffer packetSniffer = new PacketSniffer(nif);
if (args.length>0){
int time= Integer.parseInt(args[0]);
packetSniffer.setTime(time);
}
packetSniffer.startSniffing();
}
}
This is the code I have used to capture the packet on the interfaces on my system. So I'm using two systems to communicate and capture but I'm not successful.!!
I am receiving strings from my server that I want to append into a Textarea on the client side (Think chat window). Problem is, when I receive the string, the client freezes.
insertUserNameButton.setOnAction((event) -> {
userName=userNameField.getText();
try {
connect();
} catch (IOException e) {
e.printStackTrace();
}
});
public Client() {
userInput.setOnAction((event) -> {
out.println(userInput.getText());
userInput.setText("");
});
}
private void connect() throws IOException {
String serverAddress = hostName;
Socket socket = new Socket(serverAddress, portNumber);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
while (true) {
String line = in.readLine();
if (line.startsWith("SUBMITNAME")) {
out.println(userName);
} else if (line.startsWith("MESSAGE")) {
Platform.runLater(()->serverOutput.appendText(line.substring(8) + "\n"));
} else if (line.startsWith("QUESTION")) {
Platform.runLater(()->serverOutput.appendText(line.substring(8) + "\n"));
} else if (line.startsWith("CORRECTANSWER")) {
Platform.runLater(()->serverOutput.appendText(line.substring(14) + "\n"));
}
}
}
public static void main(String[] args) {
launch(args);
}
I have done some research and it seems that using Platform.runLater on each append should fix the problem. It doesn't for me.
Anyone has an idea of what it can be caused by? Thank you!
You are calling connect() on the FX Application Thread. Since it blocks indefinitely via the
while(true) {
String line = in.readLine();
// ...
}
construct, you block the FX Application Thread and prevent it from doing any of its usual work (rendering the UI, responding to user events, etc).
You need to run this on a background thread. It's best to use a Executor to manage the threads:
private final Executor exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t ;
});
and then do
insertUserNameButton.setOnAction((event) -> {
userName=userNameField.getText();
exec.execute(() -> {
try {
connect();
} catch (IOException e) {
e.printStackTrace();
}
});
});
I am trying to wrap my server and client console apps in a class so I can initialize it. When I try to code in the Client side in AppStart it won't let me call the StartClient method. It works just fine for my server, but not the client.
Here is the server class:
namespace Server
{
public class RunServer
{
// State object for reading client data asynchronously
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousSocketListener
{
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public AsynchronousSocketListener()
{
}
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content);
Random rand = new Random();
content = rand.ToString();
// Echo the data back to the client.
Send(handler, content);
}
else {
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}
private static void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}
}
}
And here is the program that initializes it:
namespace AppStart
{
class Program
{
static void Main(string[] args)
{
Server.RunServer.AsynchronousSocketListener.StartListening();
Client.RunClient.AsynchronousClient. //Won't let me call StartClient method
}
}
}
Here is the Client side:
namespace Client
{
public class RunClient
{
// State object for receiving data from remote device.
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousClient
{
// The port number for the remote device.
private const int port = 11000;
// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
private static ManualResetEvent sendDone =
new ManualResetEvent(false);
private static ManualResetEvent receiveDone =
new ManualResetEvent(false);
// The response from the remote device.
private static String response = String.Empty;
private static void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(localEndPoint,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// Send test data to the remote device.
Send(client, "This is a test<EOF>");
sendDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
// Write the response to the console.
Console.WriteLine("Response received : {0}", response);
// Release the socket.
//client.Shutdown(SocketShutdown.Both);
//client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else {
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args)
{
StartClient();
return 0;
}
}
}
}
Under here you find a simple server/client app that sends the integer 5 from the client to the server, which reads it and sends it back to the client. On the server I have placed a latency meter around the DataInputStream.readInt() method, which reads that this method is causing a 400 ms latency.
Server code:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String args[]) {
// declaration section:
ServerSocket echoServer = null;
Socket clientSocket = null;
int x;
// Try to open a server socket on port 4444
try {
echoServer = new ServerSocket(4444);
}
catch (IOException e) {
System.out.println(e);
}
//accept connection
try {
clientSocket = echoServer.accept();
//input
DataInputStream input = new DataInputStream(clientSocket.getInputStream());
//output
DataOutputStream output = new DataOutputStream(clientSocket.getOutputStream());
//loop
while(true){
long time = System.currentTimeMillis();
output.writeInt(input.readInt());
long dtime = System.currentTimeMillis();
System.out.println(dtime-time);
}
//close
// output.close();
// input.close();
// clientSocket.close();
// echoServer.close();
}catch (IOException e) {
System.out.println(e);
}
}
}
Client code:
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
// declaration section:
// clientClient: our client socket
// out: output stream
// in: input stream
Socket clientSocket = null;
// Initialization section:
// Try to open a socket on port 4444
// Try to open input and output streams
try{
clientSocket = new Socket("YOUR-IP-HERE", 4444);
//output
DataOutputStream output = new DataOutputStream(clientSocket.getOutputStream());
//input
DataInputStream input = new DataInputStream(clientSocket.getInputStream());
//loop
while(true) {
output.writeInt(5);
//System.out.println(input.readInt());
}
//close
// output.close();
// input.close();
// clientSocket.close();
}catch(Exception e) {
System.out.println("error");
}
}
}
Problem area:
//latencymeter
long time = System.currentTimeMillis();
//problem code
output.writeInt(input.readInt());
//latencymeter
long dtime = System.currentTimeMillis();
System.out.println(dtime-time);
Am I making a mistake in my code or am I not coding efficiently, please let me know.
Thanks
Solved: Adding clientSocket.setTcpNoDelay(true); on both server and client has brought the latency down to a normal 10-20 ms.
I'm trying to connect to SSH Unix server on button click (code written in actionPerformed() method). I'm using JSch for connecting to SSH server. The code is written in SwingWorker class as it is a network operation.
private void testConnectionButtonActionPerformed(java.awt.event.ActionEvent evt) {
SwingWorker<Boolean, Void> sw = new SwingWorker<Boolean, Void>(){
#Override
protected Boolean doInBackground() throws Exception {
JSch jsch = new JSch();
String host = "ServerHost";
String username = "username";
String password = "password";
Session session = jsch.getSession(username, host);
session.setPassword(password);
session.setTimeout(20000);
System.out.println("Connecting to server...");
session.connect();
return true;
}
#Override
public void done(){
try {
System.out.println(get().toString());
} catch (Exception ex) {
System.out.err(ex);
}
}
};
sw.execute();
}
But after running the with correct host, username and password details, I get the below error all the time:
com.jcraft.jsch.JSchException: timeout: socket is not established
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
at java.util.concurrent.FutureTask.get(FutureTask.java:83)
at javax.swing.SwingWorker.get(SwingWorker.java:583)
But whenever I run the same code in standalone program, I mean instead for writing actionPerformed() method, If I write it in normal method and calling from main() method. It will work. when I integrate the same code with Button Click's actionPerformed() method, it will give me above exception.
Can anyone suggest what I'm doing wrong here or any modification should be made to the code.
I tried to connect to SSH Server using "SSHJ" implementation, but I get the below error:
java.net.SocketException: Connection reset
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
at java.util.concurrent.FutureTask.get(FutureTask.java:83)
at javax.swing.SwingWorker.get(SwingWorker.java:583)
Can someone help me - how to move forward?
I took your code, wrapped it in some GUI code (and converted it to non-generics to be able to compile it with the same settings as the rest of the JSch examples). It works for me. Try this, and report what exception you get (it has a bit more exception logging).
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import com.jcraft.jsch.*;
class SwingWorkerExample {
JTextField hostField;
JTextField userNameField;
JTextField passwordField;
JPanel panel;
public SwingWorkerExample() {
JPanel p = panel = new JPanel(new GridLayout(0,2));
hostField = new JTextField(20);
userNameField = new JTextField(20);
passwordField = new JPasswordField(20);
JButton testButton = new JButton("connect!");
testButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
testConnectionButtonActionPerformed(ev);
}
});
p.add(new JLabel("host:"));
p.add(hostField);
p.add(new JLabel("user:"));
p.add(userNameField);
p.add(new JLabel("password:"));
p.add(passwordField);
p.add(testButton);
}
public JPanel getPanel() {
return panel;
}
private void testConnectionButtonActionPerformed(ActionEvent evt) {
SwingWorker sw = new SwingWorker(){
protected Object doInBackground() throws Exception {
try {
JSch jsch = new JSch();
String host = hostField.getText();
String username = userNameField.getText();
String password = passwordField.getText();
Session session = jsch.getSession(username, host);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.setTimeout(20000);
System.out.println("Connecting to server...");
session.connect();
return session;
}
catch(Exception ex) {
ex.printStackTrace();
throw ex;
}
}
public void done(){
try {
System.out.println(get());
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
sw.execute();
}
public static void main(String[] egal) {
EventQueue.invokeLater(new Runnable(){public void run() {
SwingWorkerExample ex = new SwingWorkerExample();
JFrame f = new JFrame("bla");
f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
f.setContentPane(ex.getPanel());
f.pack();
f.setVisible(true);
}});
}
}