Binding issue with smpp server using jsmpp - java

I have a java application which uses jsmpp library to send SMSs to SMSC. Application connects successfully and sends SMSs. Connection issue occurs after a week or so up time, during this up time it sends thousands of SMSs. But suddenly after few days application starts facing connection issues, some time 'Negative bind response 0x00045' and some time waiting bind response. When I check from wireshark, Application constantly sends enquire line packets and receives responses for them with status 'OK'. This means that application is connected but still it is attempting for new connection. Below is code for connection management.
I call newSession method to get session for SMS sending..
private SMPPSession newSession(BindParameter bindParam) {
SMPPSession tmpSession = null;
dbOperations = new DBOperations();
Settings settings = dbOperations.getSettings();
if (settings == null)
logger.error("ERROR: No settings found to connect to SMSC!");
else {
try {
tmpSession = new SMPPSession(remoteIpAddress, remotePort, bindParam);
tmpSession.addSessionStateListener(new MySessionStateListener());
tmpSession.setMessageReceiverListener(new DeliverReceiptListener());
tmpSession.setEnquireLinkTimer(50000);
tmpSession.setTransactionTimer(5000L);
logger.info("New session established with " + remoteIpAddress + " on port " + remotePort + " as Transmitter");
} catch (Exception er) {
gateway=null;
logger.error("Exception Occurred While making Connection with SMPP Server with IP: " + remoteIpAddress + " and port " + remotePort+" and Error is:"+er.getMessage());
}
}
return tmpSession;
}
public void reconnectAfter(final long timeInMillis) {
final Settings settings = dbOperations.getSettings();
if (settings == null) {
logger.error("No settings found to connect to SMSC!");
return;
}
new Thread() {
#Override
public void run() {
logger.info("Schedule reconnect after " + timeInMillis + " milliseconds");
try {
Thread.sleep(timeInMillis);
} catch (InterruptedException e) {
logger.error(e.getMessage());
}
int attempt = 0;
while (session == null || session.getSessionState().equals(SessionState.CLOSED)) {
try {
logger.info("Reconnecting attempt #" + (++attempt) + "...");
session = newSession(bindParam);
} catch (Exception e) {
logger.error("Failed opening Transmitter connection and bind to " + remoteIpAddress + ":" + remotePort + " ");
logger.error(e.getMessage());
// wait for a second
try {
Thread.sleep(reconnectInterval);
} catch (InterruptedException ee) {
logger.error(e.getMessage());
}
}
}
}
}.start();
}
private class MySessionStateListener implements SessionStateListener {
public void onStateChange(SessionState newState, SessionState oldState, Object o) {
if (newState.equals(SessionState.OPEN)) {
logger.info("TCP connection established with SMSC at address " + remoteIpAddress);
}
if (newState.equals(SessionState.BOUND_TRX)) {
logger.info("SMPP Transceiver connection established with SMSC at address " + remoteIpAddress + " and port " + remotePort);
}
if (newState.equals(SessionState.CLOSED) || newState.equals(SessionState.UNBOUND)) {
logger.error("Connection closed, either by SMSC or there is network problem");
if(newState.equals(SessionState.CLOSED))
logger.error("Connection closed");
else
logger.error("Connection unbound");
logger.info("Reconnecting.......");
reconnectAfter(reconnectInterval);
}
}
}
I don't why this code retries for fresh connection when it is already connected. Any clue is appreciated.

It seems the session still valid.
Make sure there are no zombie session, if there are any then close them all. It make sure the enquire link sending stop.

Related

Connect to mining pool

I am trying to etablish a connection to a monero mining pool. I know that the mining pools using the stratum protocol. But the only thing I receive is a connection timeout if I try to create a socket:
try{
InetAddress address = InetAddress.getByName("pool.supportxmr.com");
Log.d("miner","Attempting to connect to " + address.toString() + " on port " + port + ".");
Socket socket = new Socket(address, 3333);
Log.d("miner", "Connection success");
}catch (IOException e){
e.printStackTrace();
}
SupportXmr is just an example. Its not working with any pool. What am I doing wrong?
Try with port 80. Make sure you wrote INTERNET permission to AndroidManifest and use AsnycTask.
private class AsyncExec extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... voids) {
int port=80;
try
{
InetAddress address = InetAddress.getByName("pool.supportxmr.com");
Log.d("miner","Attempting to connect to " + address.toString() + " on port " + port + ".");
Socket socket = new Socket(address, 3333);
Log.d("miner", "Connection success");
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
}
- Also don't forget to call new AsyncExec().execute().

Java - how can I check if the ServerSocket.accept()ed the connection?

I'm trying to write simple server-client chat solution. For test purposes, I'm creating an array of 2 serverThreads, which are responsible for sending and receiving messages from the clients connected.
I'd like a server to reject a connections after the number of connected clients reach a maximum value. However, even though the server do not accept the connection, the socket on client side is created. Methods socket.isBound and isConnected both return true value.
So back to the main question. Do you have any ideas how could I reject the client from connecting when the ServerSocket will not be able to .accept() additional connection?
Here's the code of the Server class.
public class Server {
private ServerSocket serverSocket = null;
private ServerThread serverThread[] = new ServerThread[2];
protected volatile int clientCount = 0;
public Server (int port){
try {
System.out.println("Binding to port " + port + " ...");
serverSocket = new ServerSocket (port);
System.out.println("Binded to port " + port + ".");
} catch (IOException e) {
System.out.println("Failed binding to the port: " + e.getMessage());
}
}
public void addThread (Socket socket){
System.out.println ("Client connected at socket: " + socket);
serverThread[clientCount] = new ServerThread (this, socket);
try {
serverThread[clientCount].open();
serverThread[clientCount].start();
} catch (IOException e) {e.getMessage();}
}
public void waitForClient () {
boolean isLogPrinted = false;
while (true){
try {
if (clientCount < serverThread.length){
System.out.println ("Waiting for connection...");
isLogPrinted = false;
addThread (serverSocket.accept());
clientCount++;
System.out.println("Client count: " + clientCount);
}
else {
if (!isLogPrinted){
System.out.println("MAXIMUM NUMBER OF CLIENTS REACHED! (" + clientCount + ").");
isLogPrinted = true;
}
}
} catch (IOException e) {
System.out.println("Error while waiting for new clients to connect: " + e.getMessage());
}
}
}
public synchronized void broadcastMessages (String msg){
for (int i = 0; i < clientCount; i++)
serverThread[i].sendMessage(msg);
}
public static void main (String args[]){
Server server = new Server (4200);
server.waitForClient();
}
}
I'd like a server to reject a connections after the number of connected clients reach a maximum value.
Close the server socket.
However, even though the server do not accept the connection, the socket on client side is created. Methods socket.isBound and isConnected both return true value.
Correct. That's because TCP maintains a 'backlog queue' of incoming connections which have been completed but not yet accepted by the server application.
So back to the main question. Do you have any ideas how could I reject the client from connecting when the ServerSocket will not be able to .accept() additional connection?
Close the server socket while the number of connections is at its maximum.
However due to the backlog this technique can never be perfect. There is no perfect solution. You could have the server immediately close excess connections, but the excess clients won't detect that until they try to send something. If you need perfection you will probably have to introduce an application protocol whereby the server sends something like 'ACCEPTED' or 'REJECTED' accordingly.
Instead of while true in you waitForClient method try this
private final int allowedClients = 10;
private int connectedClients = 0;
public void waitForClient () {
boolean isLogPrinted = false;
while (connectedClients <= allowedClients){
try {
if (clientCount < serverThread.length){
System.out.println ("Waiting for connection...");
isLogPrinted = false;
addThread (serverSocket.accept());
connectedClients++;
System.out.println("Client count: " + clientCount);
}
else {
if (!isLogPrinted){
System.out.println("MAXIMUM NUMBER OF CLIENTS REACHED! (" + clientCount + ").");
isLogPrinted = true;
}
}
} catch (IOException e) {
System.out.println("Error while waiting for new clients to connect: " + e.getMessage());
}
}
}
I know this is very late to answer, but I think it will help many.
You can check for the existing socket if any by below code.
SocketAddress socketAddress = new InetSocketAddress("localhost", 8091);
Socket socket = new Socket();
ServerSocket serverSocket = null;
try {
socket.connect(socketAddress);
} catch (IOException e) {
e.printStackTrace();
}
if(socket == null) {
try {
serverSocket = new ServerSocket(8091);
} catch (IOException e) {
e.printStackTrace();
}
}
if not found a active socket on the same port and IP then it will start a new server socket or you can change it start socket only else you can connect to the existing socket.

Why does my server PrintWriter.println() fail to send its message over a socket?

I know what you are going to say "use .flush()"....I am. What I have done is build a program that will synchronize 3 machines based on the messages sent from the client.
Here is the algorithm I am using:
Connect all client machines to 1 server machine
Each client machine gets to the point where it is ready to execute (this is the "syncing" part" so it sends a "ready" flag to the server)
Once all machines have sent the "ready" flag via socket, the server sends back "execute" via PrintWriter and the client machines and they execute and finish that iteration
After the client has finished executing it sends a "reset" flag back to the server and the server gets ready to start all over (the server doesn't care how many times this will happen)
Each client then moves on to the next iteration to do the same exact thing, gets "ready", and then when all are "ready", server sends "execute" again <- this is were the problem is. My Printwriter.println("execute") is supposedly sent but is NEVER received on any of the client machines.
Just to reiteration and be clear, the first time this proccess is carried out, everything go's as expected, on the second iteration, the "execute" command is never sent to the client even though it executes the out.println("execute) line.
Am I doing something wrong? I have also tried PrintStream and see the same problem ever time. Am I handling the BufferedReader wrong? For the life of me I cannot understand why everything works as expected the first time around but then after the second time "execute" is never sent to the client machines. Any help will be much appreciated.
Server snipit:
StartServerResponseThread() Is called after server has accepted the client.
// Init the nuc client
public void NucClientInit(Socket s) {
new Thread() {
public void run() {
try {
socket = s;
bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
// socket.getOutputStream(), "UTF-8")), true);
brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
// Start the reponse thread
StartServerResponseThread();
// Confirm connection to client
ConfirmConnection();
} catch (IOException ex) {
Logger.Log("Nuc:NucClientInit:IOException:ex: " + ex);
}
}
}.start();
}
// Sends connect and waits for reponse back from server
private void ConfirmConnection() {
Logger.Log("Sending connect to: " + ip_address);
try {
bufOut.write("connect");
bufOut.newLine();
bufOut.flush();
} catch (IOException ex) {
Logger.Log("Nuc:ConfirmConnection():bufOut:ex " + ex);
}
Logger.Log("Sent connect: " + ip_address);
while (!connected) {
}
Logger.Log(ip_address + " Client is successfully Connected!");
}
// Handles any message from server
private void HandleClientMessage(String message) {
switch (message) {
case "connect":
// Flag connection to confirm client connected (see ConfirmConnection())
connected = true;
break;
case "ready":
Logger.Log("Nuc:" + ip_address + ":received:ready");
// Nuc is ready for sync now
SetNucIsReady(true);
break;
case "reset":
// Nuc has finished test (probably interleave)
SetNucIsReady(false);
break;
default:
Logger.Log("UNHANDLED CLIENT RSPONSE!!");
}
}
// Will always run in a separate thread waiting for any response
// from the server
private void StartServerResponseThread() {
new Thread() {
public void run() {
try {
while ((fromClient = brffReadIn.readLine()) != null) {
HandleClientMessage(fromClient);
}
} catch (IOException ex) {
Logger.Log("Nuc:StartServerResponseThread():IOException:ex: " + ex);
}
} // Close run()
}.start();
}
// This method is used to send the execute command to the Nuc machine tied
// to this object.
public void Execute() {
try {
bufOut.write("execute");
bufOut.newLine();
bufOut.flush();
Logger.Log(("Class:Nuc:method:Execute:" + ip_address + " sent "
+ "execute command"));
} catch (IOException ex) {
Logger.Log("Nuc:Execute():IOException:ex: " + ex);
}
}
Client:
// Tell Server ready to execute
static void SendReady(){
try {
bufOut.write("ready");
bufOut.newLine();
bufOut.flush();
} catch (IOException ex) {
log("KPI_Socket:SendReady():bufOut:ex " + ex);
}
log("Sent to Server 'ready'");
}
// Wait until execute is received from server
static void WaitForExecute(){
log("Waiting for execute command from server");
while(!execute){
}
log("Execute received from Server!");
execute = false;
}
// Tell server nuc needs to reset its isReady boolean
static void SendServerReset(){
try {
bufOut.write("reset");
bufOut.newLine();
bufOut.flush();
} catch (IOException ex) {
log("KPI_Socket:SendServerReset():bufOut:ex " + ex);
}
log("Sent to Server 'reset'");
}
// Inform user connection is good
static void HandleConnect(){
connected = true;
log("Client Now Connected To Server");
}
// Handles any response from the server
static void HandleServerResponse(String serverResponse){
switch (serverResponse){
case "connect":
HandleConnect();
break;
case "execute":
execute = true;
HandleExecute();
default:
log("UHANDLED RSPONSE FROM SERVER!!")
}
}
// Will always run in a separate thread waiting for any response
// from the server
static void StartServerResponseThread(){
new Thread(){
public void run(){
while ((fromServer = brffReadIn.readLine()) != null) {
log("Message from Server: '" + fromServer + "'");
HandleServerResponse(fromServer);
}
log("StartServerResponseThread() CLOSED!!!!!!!!");
} // Close run()
}.start();
}
// Init all components, connect to server and start server response thread
static void ConnectToServer(String host, int port){
hostname = host;
portNumber = port;
try {
log("Attempting to connect to " + hostname + "\n");
socket = new Socket(hostname, portNumber);
log("Connected to " + hostname);
bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
// socket.getOutputStream(), "UTF-8")), true);
brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
// Start the server response thread to run in background
StartServerResponseThread();
// Wait for response from server on connect message
while(!connected){
log("Waiting for greeting message from server");
wait_for(1);
}
try {
bufOut.write("connect");
bufOut.newLine();
bufOut.flush();
} catch (IOException ex) {
log("KPI_Socket:ConnectToServer():bufOut:ex " + ex);
}
} catch (UnknownHostException e) {
log("KPI_Socket:ConnectToServer():UnknownHostException" + e);
} catch (IOException e) {
log("KPI_Socket:ConnectToServer():IOException: " + e);
}
} // Close ConnectToServer();
I know what you are going to say "use .flush()"...
No I'm not. I'm going to say 'don't use PrintWriter'. It swallows exceptions. Use BufferedWriter, write(), newline(), and flush(). That way if there are any exceptions, you'll see them. With PrintWriter, you can't.

acceptAndOpen() method error

I am making a bluetooth related application to browse the internet.. With Server as laptop/desktop and client as the mobile phone.. i need to establish a connection between client and server.. but the execution of the server suddenly stops at the method acceptAndOpen() .. Please help to solve the problem.. this is the code where it stops in the server side:
while (mServerState) {
StreamConnection btConn = null;
try {
updateStatus("[server:] Now waiting for a client to connect");
//here is the error
btConn = (StreamConnection) btServerNotifier.acceptAndOpen();
RemoteDevice dev = RemoteDevice.getRemoteDevice(btConn);
System.out.println("Remote device address: " + dev.getBluetoothAddress());
updateStatus("Remote device " + dev.getFriendlyName(true) + "connected");
} catch (IOException ioe) {
}
if (btConn != null) {
processConnection(btConn);
}
}

Can't Connect to Openfire server

I am trying to connect to an openfire server using smack API, I am unable to do so.
Here is the code:
public class Tests{
public static void main( String[] args ) {
System.out.println("Starting IM client");
// gtalk requires this or your messages bounce back as errors
ConnectionConfiguration connConfig = new ConnectionConfiguration("localhost", 5222);
XMPPConnection connection = new XMPPConnection(connConfig);
try {
connection.connect();
System.out.println("Connected to " + connection.getHost());
} catch (XMPPException ex) {
//ex.printStackTrace();
System.out.println("Failed to connect to " + connection.getHost());
System.exit(1);
}
try {
connection.login("test#example.com", "setup1");
System.out.println("Logged in as " + connection.getUser());
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
} catch (XMPPException ex) {
//ex.printStackTrace();
System.out.println("Failed to log in as " + connection.getUser());
System.exit(1);
}
connection.disconnect();
}
}
The following is the output:
Starting IM client
Connected to localhost
Failed to log in as null
It seems to connect to the server but can't log in.
connection.login("test#example.com", "setup1");
You definitely shouldn't be logging in to example.com domain if your server is started on localhost.
Try just:
connection.login("test", "setup1");
But remember that to be able to login, you need to have a valid username and password. That means you have to create user "test" with password "setup1" on your server.

Categories