socket inputstream issue in j2me (BB) - sockets

I am working on XMPP client for BB with JXA, but JXA api takes time to read from inputstream and through timeout error after 2 mins. I written seperate socket program in J2ME and executed in the BB simulator, it could exchange XML but the inputstream is not quitting from the while loop, gets hang in reading. Please see the below code..
class SocketThread extends Thread
{
public void run()
{
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection("socket://xxxxxx.p1.im:5222");
if (connDesc != null)
{
SocketConnection httpConn;
httpConn = (SocketConnection)connDesc.getConnection();
try
{
InputStream is = httpConn.openInputStream();
OutputStream os = httpConn.openOutputStream();
String a = "<?xml version=\"1.0\"?><stream:stream to=\"xxxxx.p1.im\" xml:lang=\"en\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\">";
os.write(a.getBytes());
byte[] b = new byte[1024];
int len =0;
while ((len = is.read(b)) > 0) {
String str = new String(b);
System.out.println("Server n: " + str);
}
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("got response xml stream..: "
);
}
});
}
catch (IOException e)
{
System.err.println("Caught IOException: "
+ e.getMessage());
}
}
}
}
Above program not coming out of the loop unless until it timesout, please help me out to fix this issue to move forward.
Thanks in advance.

A read timeout means no data arrived within the timeout period. Nothing else.
Your code is wrong in other ways however: you are assuming the read filled the buffer, and ignoring positive values of 'len' when constructing the String, so you are passing yourself junk.

Related

Can't read/write data (TcpClient/NetworkStream)

A former employees used TCP Client & TCP Listener, Thread, and NetworkStream to create a payment server with Unity 32-bit for Unity 32-bit games and payment connections.
(I don't know what I'm talking about either)
BUT Only the first payment is successful, and the second payment cannot be 'Read' even if it is 'Write'.
(Or maybe client server listener(?) is dumb.... ;( )
So I tried debugging, but this comment came up.
'SocketException System.Net.Sockets.SocketException: Blocking operation aborted by calling WSACanceBlockingCall.'
I can't even connect to the clientServer.
It's fatal to the company that only one payment is made.
This is because after the payment, the game proceeds and when the GameLife is exhausted, you have to return to the lobby and pay again.
But "Write" works, but why doesn't it go on after that?
If you are disconnected from the game and payment server, you will be warned that you are disconnected from the server.
I'm so confused. I'm a client developer and I don't understand anything because I think I'm developing a server.
I'm just a three-month-old junior developer...
This is my client Write Code
public void SendMessage()
{
if (socketConnection == null)
{
return;
}
try
{
// Get a stream object for writing.
NetworkStream stream = socketConnection.GetStream();
if (stream.CanWrite)
{
//string clientMessage = "This is a message from one of your clients.";
string clientMessage = string.Format("Charge,{0}",DataManager.instance.payData._Money);
// Convert string message to byte array.
//byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage);
byte[] clientMessageAsByteArray = Encoding.UTF8.GetBytes(clientMessage);
// Write byte array to socketConnection stream.
stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length);
Debug.Log("Client sent his message - should be received by server");
}
}
catch (SocketException socketException)
{
serverState = ServerState.Disconnect;
Debug.Log("Socket exception: " + socketException);
}
}
This is Server Read Code
private void ListenForIncomingRequests()
{
try
{
// Get Local IPv4 Address
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
address = ip.ToString();
}
}
Debug.Log("address : "+ address);
// Create listener on localhost port 8052.
tcpListener = new TcpListener(IPAddress.Parse(address), 50001);
tcpListener.Start();
Debug.Log("Server is listening");
Byte[] bytes = new Byte[1024];
while (true)
{
using (connectedTcpClient = tcpListener.AcceptTcpClient())
{
Debug.Log(connectedTcpClient.ToString());
// Get a stream object for reading
using (NetworkStream stream = connectedTcpClient.GetStream())
{
int length;
// Read incoming stream into byte arrary.
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0)
{
var incomingData = new byte[length];
Array.Copy(bytes, 0, incomingData, 0, length);
// Convert byte array to string message.
//string clientMessage = Encoding.ASCII.GetString(incomingData);
string[] message = Encoding.UTF8.GetString(incomingData).Split(',');
string clientMessage = message[0];
string value = message[1];
if (string.IsNullOrEmpty(_clientMessage))
{
_clientMessage = clientMessage;
if (_clientMessage.Equals("Charge"))
{
_clientMessage = string.Empty;
pay.PayEvent(int.Parse(value));
}
}
Debug.Log("client message received as: " + clientMessage);
Debug.Log("_client message received as: " + _clientMessage);
Debug.Log(length);
}
}
}
}
}
catch (SocketException socketException)
{
Debug.Log("SocketException " + socketException.ToString());
}
}

FIX:How to send ,messages using FIX ,quickfixj

# Here is my settings.cfg file:
# Thank you.Here is what i tried.My settings.cfg file
[DEFAULT]
# Settings which apply to all the Sessions.
ConnectionType=initiator
LogonTimeout=30
ReconnectInterval=20
ResetOnLogon=Y
FileLogPath=C:\Work\QuickFIXJ\logs
FileStorePath=C:\Work\QuickFIXJ\logs
[SESSION]
# Settings specifically for one session
BeginString=FIX.4.4
SenderCompID=XYZ
TargetCompID=TYZ
TimeZone=Asia/Tokyo
StartTime=16:00:00
EndTime=13:30:00
HeartBtInt=60
SocketConnectPort=7200
SocketConnectHost=123.123.123.123
UseDataDictionary=Y
DataDictionary=C:\Work\QuickFIXJ\datadictionary\FIX44.xml
[GATEWAY]
Port=4444
[TRANSPORT]
Port=4444
and then
//initiator code:
public class TestQuickFixJConnectivity {
public static void main(String[] args) {
SocketInitiator socketInitiator = null;
try {
SessionSettings sessionSettings = new SessionSettings("C:\\Work\\QuickFixJ\\sessionSettings.txt");
Application application = new TestApplicationImpl();
FileStoreFactory fileStoreFactory = new FileStoreFactory(sessionSettings);
FileLogFactory logFactory = new FileLogFactory(sessionSettings);
MessageFactory messageFactory = new DefaultMessageFactory();
socketInitiator = new SocketInitiator(application,
fileStoreFactory, sessionSettings, logFactory,
messageFactory);
socketInitiator.start();
SessionID sessionId = socketInitiator.getSessions().get(0);
sendLogonRequest(sessionId);
int i = 0;
do {
try {
Thread.sleep(1000);
System.out.println(socketInitiator.isLoggedOn());
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
} while ((!socketInitiator.isLoggedOn()) && (i < 30));
} catch (ConfigError e) {
e.printStackTrace();
} catch (SessionNotFound e) {
e.printStackTrace();
} catch (Exception exp) {
exp.printStackTrace();
} finally {
if (socketInitiator != null) {
socketInitiator.stop(true);
}
}
}
private static void sendLogonRequest(SessionID sessionId) throws SessionNotFound {
Logon logon = new Logon();
Message msg=new Message();
Header header = msg.getHeader();
logon.set(new HeartBtInt(60));
logon.set(new ResetSeqNumFlag(true));
header.setField(new BeginString("FIX.4.4"));
header.setField(new MsgType("AP"));
header.setField(new SenderCompId("XYZ"));
header.setField(new TagetCompId("TYZ"));
header.setField(new ResetSeqNumFlag(true));
//here i m setting all the fields in the csv report .
msg.setField(705,new SortQty(""));
// ....
//below statement returning false
boolean sent = Session.sendToTarget(msg, sessionId);
System.out.println("Logon Message Sent : " + sent);
}
}
Please find my observations below:
In the event logs I am seeing as Created session: and the message which I am trying to send. Also I could see that the sender sequence number is getting incremented in the logs.
Messages.log and header.logs are blank and body.log has the message which i am trying to send.
Also onCreate and ToApp are being called when I try to run the code.
I want to know whether i have sent the message successfully ?
Also boolean sent = Session.sendToTarget(msg, sessionId); is returning false.
I don't see ToAdmin and FromAdmin being executed in my code. Also Do I need to write the acceptor code as well for the same, or just the initiator code will be fine. The DataDictionary which i am using has all the fields set, but I am not sure whether its being used by QuickFixJ when i try to execute the code.
Please advise whats going wrong in this?
OK your settings file looks ok and you're saying it works, but I don't think you need GATEWAY and TRANSPORT headings
As for your code, all you need to do to start with is setup the default QuickFIX Application, FileStoreFactory, LogFactory, MessageFactory and Initiator which you have done.
The default QuickFIX automatically logs on to the Target in your settings file, and if the logon is accepted then it begins to heartbeat. From your comments it sounds like this is happening.
So what's going wrong is your sendLogonRequest is not necessary. Also, if you do send "extra" logons then the target FIX engine will probably reject or ignore them. The reject message would be seen in the logs or file store.
So then you have the QuickFIX API with which to start with you can simply output messages to your own log.
Something like this
public void fromApp(Message msg, SessionID s) throws UnsupportedMessageType, FieldNotFound, IncorrectTagValue
{
log.debug(String.valueOf(LocalTime.now()) + " INITIATOR: FromApp " + msg.toString());
}
public void toApp(Message msg, SessionID s)
{
log.info(String.valueOf(LocalTime.now()) + " INITIATOR: ToApp " + msg.toString());
}
public void fromAdmin(Message msg, SessionID s) throws FieldNotFound, IncorrectTagValue
{
Log.trace("INITIATOR: FromAdmin " + msg.getClass() + " " + msg.toString());
}
public void onCreate(SessionID s)
{
log.info("INITIATOR: OnCreate " + s.toString());
}
public void onLogout(SessionID s)
{
log.error("INITIATOR: OnLogout " + s.toString());
}
public void onLogon(SessionID s)
{
log.info("INITIATOR: OnLogon " + s.toString());
}
public void toAdmin(Message msg, SessionID s)
{
log.trace("INITIATOR: ToAdmin " + msg.getClass() + " " + msg.toString());
}
Then when you want to send a message, try something like this:
QuoteReqID id = new QuoteReqID("1234");
// Create Quote Request message
QuoteRequest qr = new QuoteRequest(id);
// Setup outgoing group and specify an index for each group tag
NoRelatedSym g = new NoRelatedSym();
String instrument = m.getString("EUR/USD");
Symbol symbol = new Symbol(instrument);
g.setField(1, symbol);
QuoteRequestType qt = new QuoteRequestType(102);
g.setField(2, qt);
OrderQty qty = new OrderQty("1000000");
g.setField(3, qty);
SettlType sType = new SettlType("B");
g.setField(4, sType);
SettlDate sDate = new SettlDate("20170315");
g.setField(5, sDate);
Account account = new Account("357647");
g.setField(6, account);
// add group to request
qr.addGroup(g);
Session s = Session.lookupSession(i.getSessions().get(0));
s.send(qr);

netty issue when writeAndFlush called from different InboundChannelHandlerAdapter.channelRead

I've got an issue, for which I am unable to post full code (sorry), due to security reasons. The gist of my issue is that I have a ServerBootstrap, created as follows:
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
final ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, 3000));
//Adds the MQTT encoder and decoder
ch.pipeline().addLast("decoder", new MyMessageDecoder());
ch.pipeline().addLast("encoder", new MyMessageEncoder());
ch.pipeline().addLast(createMyHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128).option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_KEEPALIVE, true);
// Bind and start to accept incoming connections.
channelFuture = b.bind(listenAddress, listenPort);
With createMyHandlerMethod() that basically returns an extended implementation of ChannelInboundHandlerAdapter
I also have a "client" listener, that listens for incoming connection requests, and is loaded as follows:
final String host = getHost();
final int port = getPort();
nioEventLoopGroup = new NioEventLoopGroup();
bootStrap = new Bootstrap();
bootStrap.group(nioEventLoopGroup);
bootStrap.channel(NioSocketChannel.class);
bootStrap.option(ChannelOption.SO_KEEPALIVE, true);
bootStrap.handler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, getKeepAliveInterval()));
ch.pipeline().addAfter("idleStateHandler", "idleEventHandler", new MoquetteIdleTimeoutHandler());
ch.pipeline().addLast("decoder", new MyMessageDecoder());
ch.pipeline().addLast("encoder", new MyMessageEncoder());
ch.pipeline().addLast(MyClientHandler.this);
}
})
.option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.TCP_NODELAY, true);
// Start the client.
try {
channelFuture = bootStrap.connect(host, port).sync();
} catch (InterruptedException e) {
throw new MyException(“Exception”, e);
}
Where MyClientHandler is again a subclassed instance of ChannelInboundHandlerAdapter. Everything works fine, I get messages coming in from the "server" adapter, i process them, and send them back on the same context. And vice-versa for the "client" handler.
The problem happens when I have to (for some messages) proxy them from the server or client handler to other connection. Again, I am very sorry for not being able to post much code, but the gist of it is that I'm calling from:
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(someOtherMessage);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
Now here's the problem: the bolded (client) writeAndFlush - never actually writes the message bytes, it doesn't throw any errors. The ChannelFuture returns all false (success, cancelled, done). And if I sync on it, eventually it times out for other reasons (connection timeout set within my code).
I know I haven't posted all of my code, but I'm hoping that someone has some tips and/or pointers for how to isolate the problem of WHY it is not writing to the client context. I'm not a Netty expert by any stretch, and most of this code was written by someone else. They are both subclassing ChannelInboundHandlerAdapter
Feel free to ask any questions if you have any.
*****EDIT*********
I tried to proxy the request back to a DIFFERENT context/channel (ie, the client channel) using the following test code:
public void proxyPubRec(int messageId) throws MQTTException {
logger.log(logLevel, "proxying PUBREC to context: " + debugContext());
PubRecMessage pubRecMessage = new PubRecMessage();
pubRecMessage.setMessageID(messageId);
pubRecMessage.setRemainingLength(2);
logger.log(logLevel, "pipeline writable flag: " + ctx.pipeline().channel().isWritable());
MyMQTTEncoder encoder = new MyMQTTEncoder();
ByteBuf buff = null;
try {
buff = encoder.encode(pubRecMessage);
ctx.channel().writeAndFlush(buff);
} catch (Throwable t) {
logger.log(Level.SEVERE, "unable to encode PUBREC");
} finally {
if (buff != null) {
buff.release();
}
}
}
public class MyMQTTEncoder extends MQTTEncoder {
public ByteBuf encode(AbstractMessage msg) {
PooledByteBufAllocator allocator = new PooledByteBufAllocator();
ByteBuf buf = allocator.buffer();
try {
super.encode(ctx, msg, buf);
} catch (Throwable t) {
logger.log(Level.SEVERE, "unable to encode PUBREC, " + t.getMessage());
}
return buf;
}
}
But the above at line: ctx.channel().writeAndFlush(buff) is NOT writing to the other channel - any tips/tricks on debugging this sort of issue?
someOtherMessage has to be ByteBuf.
So, take this :
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(someOtherMessage);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
... and replace it with this :
serverHandler.channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof myProxyingMessage) {
if (ctx.channel().isActive()) {
ctx.channel().writeAndFlush(ByteBuf);
**getClientHandler().writeAndFlush(myProxyingMessage);**
}
}
}
Actually, this turned out to be a threading issue. One of my threads was blocked/waiting while other threads were writing to the context and because of this, the writes were buffered and not sent, even with a flush. Problem solved!
Essentially, I put the first message code in an Runnable/Executor thread, which allowed it to run separately so that the second write/response was able to write to the context. There are still potentially some issues with this (in terms of message ordering), but this is not on topic for the original question. Thanks for all your help!

Servlet call hanging when using S3 Java SDK

I have this servlet I call using GWT FileUpload (I don't thing it matters so much that it is GWT):
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
try {
User user = ServerUtil.validateUser(request);
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String saveFile = item.getName();
InputStream stream = item.openStream();
// Process the input stream
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[8192];
while ((len = stream.read(buffer, 0, buffer.length)) != -1) {
out.write(buffer, 0, len);
}
int maxFileSize = 10 * (1024 * 1024); //10 megs max
if (out.size() > maxFileSize) {
throw new RuntimeException("File is > than " + maxFileSize);
}
// save file data
String fileName = user.getUsername() + "_" + new Date().getTime() + "_" + saveFile;
// store to S3
String imageUrl = S3PhotoUtil.storeThumbnailImage(out.toByteArray(), fileName, 100);
// return the url of the file
writer.println(imageUrl);
response.flushBuffer();
return;
}
} catch (RuntimeException e) {
writer.println(("error=" + e.getMessage()).getBytes());
} catch (FileUploadException e) {
writer.println(("error=Could not read file").getBytes());
} catch(IOException e) {
writer.println(("error=Image type not supported!").getBytes());
}
} catch (EIException e) {
e.printStackTrace();
writer.println(("error=Not logged in").getBytes());
}
}
When called the POST hangs, I check on firebug, it looks like it never gets a response. If I debug I see that all instructions are executed without any problem and the method is ran fine. The files are stored on my S3 bucket.
Now if I remove the call relating to the S3 storage it stops hanging, although obviously it doesn't do anything anymore... My conclusion is that there is something in this S3 storage that messes up with my servlet. The code itself is taken from the travel log example application # http://aws.amazon.com/code/1264287584622066
It does say needs tomcat and I'm using jetty... could that be a problem?
Thanks,
Thomas

Java socket programming problem

Hey,
I am trying to run this socket programming code.
This is the code on the server side -
package sockettest;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(139);
}
catch (IOException e)
{
System.err.println("not able to listen on port");
System.exit(1);
}
Socket clientSocket = null;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); // Out is Outputstream is used to write to the Client .
BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); // in is used to read the Client's input.
String inputLine, outputLine;
out.println("Hey! . Who are you?"); // Writes to client as "Hey! . Who are you?"
while ((inputLine = in.readLine()) != null)
{
// Reads the input from the Client. if it is "bye" the program ends.
if (inputLine.equalsIgnoreCase("Bye"))
{
out.println("Bye");
break;
}
else
{
out.println("Hello Mr. " + inputLine);
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
This is the code running on the client side -
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try
{
kkSocket = new Socket("192.168.2.3", 139);
out = new PrintWriter(kkSocket.getOutputStream(), true); // Out may be used to write to server from the client
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream())); // in will be used to read the lines sent by the Server.
}
catch (UnknownHostException e)
{
System.err.println("Unidentified host.");
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromClient;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye"))
break;
fromClient = stdIn.readLine();
if (fromClient != null) {
System.out.println("Client: " + fromClient);
out.println(fromClient);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
I'm running the codes on eclipse in both the client and the server side. Using netstat -an command in cmd prompt, i can see that a connection has been established between the client and the server but i cannot communicate and eclipse is not showing any output too. What seems to be wrong??
You haven't told us what the problem is. However, from a cursory glance at your code, I would advise against listening on port 139 as this is already used by NetBios under Windows and may cause a conflict.
also your Server code is missing
the initialization of inputLine,
e.g
String inputline = "";
before the while loop
keep in mind that Socket's are blocked if you read or write...
your client is reading all the time because it waits for every information on the server
until it is null
and your server also reads all the time and is waiting for any input..
so as long as server and client are waiting for input, no one will receive any data.
try to think of a protocol to communicate between the server and the client.
e.g
Sever to Client: Hello Who are you?
Client receives Data and replies: Client
Server receives Information: You Are now authorized, what ya gonna do?
and so on ^^
also out.flush() is needed to send a message