Multi-buffer socket channelling
Why does this stupid pixel grabber copy the last row and put it at the beginning?!?!? I have no clue why?! Whenever i run the code, the display shows me that the bottom row of a picture is COPIED to the top row... I DIDN'T TELL IT TO DO THIS!!! please help
public void sendData( SocketChannel sChannel)
int w = image.getWidth();
int h = image.getHeight();
int array[] = new int[w*h];
PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h+1, array, 0, w);
try
pg.grabPixels();
catch (InterruptedException e)
image.getRGB( 0, 0, w, h, array, 0, 0 );
ByteBuffer dimensionsX = ByteBuffer.allocateDirect(32);
ByteBuffer dimensionsY = ByteBuffer.allocateDirect(32);
ByteBuffer bufAlp = ByteBuffer.allocateDirect(w*h);
ByteBuffer bufRed = ByteBuffer.allocateDirect(w*h);
ByteBuffer bufGre = ByteBuffer.allocateDirect(w*h);
ByteBuffer bufBlu = ByteBuffer.allocateDirect(w*h);
try
dimensionsX.put( (byte)w );
dimensionsY.put( (byte)h );
//System.out.println( dimensionsX.get(0)&0xff );
int g = 0;
while ( g < array.length )
bufAlp.put( (byte)((array[g]>>24)&0xff) );
bufRed.put( (byte)((array[g]>>16)&0xff) );
bufGre.put( (byte)((array[g]>>8 )&0xff) );
bufBlu.put( (byte)((array[g] )&0xff) );
System.out.print( "(" + (bufAlp.get(g)&0xff) + ","
+ (bufRed.get(g)&0xff) + ","
+ (bufGre.get(g)&0xff) + ","
+ (bufBlu.get(g)&0xff) + ")" );
g++;
bufAlp.flip();
bufRed.flip();
bufGre.flip();
bufBlu.flip();
dimensionsX.flip();
dimensionsY.flip();
int nbw = 0; //number of bits written
nbw = sChannel.write(dimensionsX);
nbw = sChannel.write(dimensionsY);
nbw = sChannel.write(bufAlp);
nbw = sChannel.write(bufRed);
nbw = sChannel.write(bufGre);
nbw = sChannel.write(bufBlu);
catch (IOException e)
}
(a) Are you getting an IOException? Don't ever write empty catch blocks like that.
(b) Are you in non-blocking mode?
(c) Are you checking the return value of all the writes? There's no guarantee that all the data gets written.
Similar Messages
-
Reading lots of bytes from a socket channel
Hello,
I have a client/server architecture.
My server writes() to a socketChannel the contents large byteBuffer.
On my client, I read() the socketChannel in to a byteBuffer. However, the data I wrote to the socketChannel is so large that it doesn't all arrive in one read(). I get a byteBuffer, but it isn't complete.
Is there any way to know that there is more data waiting on the socketChannel, as it were? Or do I need to handle this myself by keeping track of the number of incoming bytes?
Cheers!I was wondering whether Java had any kind of internal way of saying "I've not yet finished writing what I was told to write....there's more data to come".Socket.Channel.write() returns a byte count. If it's less that you expect, the write was incomplete.
I suspect the answer is "no"No, the answer is 'yes', unless you are ignoring the return value.
The canonical way to write a buffer is this:
while (buffer.position() > 0)
try
buffer.flip();
int rc = channel.write(buffer);
if (rc == 0)
// Here you must register the channel for OP_WRITE
// and wait for it to trigger before trying again, not shown.
key.interestOps(SelectionKey.OP_WRITE);
break;
finally
buffer.compact();
if (buffer.position() == 0)
// The entire buffer has been written.
// At this point you deregister the channel for OP_WRITE,
key.interestOps(0);
// or more probably re-register for OP_READ.
key.interestOps(SelectionKey.OP_READ);
} -
Reg. Socket Channel Write Method
Hi,
We have the following method to write into the socket channel.
private void write(SelectionKey key)
SocketChannel channel = (SocketChannel) key.channel();
try
channel.write(writeBuffer);
key.interestOps(SelectionKey.OP_READ);
catch (IOException ioEx)
LogUtility.log(Level.SEVERE, ioEx);
My doubt is, in case of any network related issues and network goes down, how to trap those exception. In those cases, i need to re-establish the connection again to the remote host.
I tried to check, whether channel.isConnected b4 writing, but the doc says this will return false if the connect operation is never fired.
It will be helpful for me, if some one gimme an idea to proceed on this.
Best Regards,
K.SathishkumarIf you get any IOException or SocketException other than a SocketTimeoutException when doing I/O to a socket or SocketChannel you must close the socket/channel. It is of no further use. What else you do depends on the application - log it, maybe try to re-establish the connection if you are a client, forget about it if you are a server.
BTW:
We have the following method to write into the socket channel.
private void write(SelectionKey key)
SocketChannel channel = (SocketChannel) key.channel();
try
channel.write(writeBuffer);
key.interestOps(SelectionKey.OP_READ);This is not valid. You shouldn't throw away the result of the write and just assume the data got written as you are doing here. You should do something like this:
try
// assuming the buffer is already flipped
int count;
while (writeBuffer.hasRemaining() && (count = channel.write(writeBuffer)) > 0)
if (count == 0)
key.interestOps(SelectionKey.OP_WRITE);
else
key.interestOps(SelectionKey.OP_READ);
catch (IOException ioEx)
LogUtility.log(Level.SEVERE, ioEx);
try
channel.close();
catch (IOException ioEx2)
LogUtility.log(Level.SEVERE, ioEx2);
// ...} -
Using a selector to detect closed socket channel.
Basically our app uses one thread to perform a select on multiple socket channels. When a socket is closed (either remotely or locally) the server app needs to unregister the client (so we need to detect closed channels). We've been using blocking IO previously (no dramas), but now we're dealing with many connections/clients we need to rework it as we're getting excessive amounts of threads. Anyway, that's just background.
Here's the problem we're getting, I have boiled it down to the following.
SocketChannel channel = SocketChannel.open();
channel.connect(socketAddress); // for the test this is localhost.
// this make sure socket is open, remote end just echos, waits 3 seconds and closes the socket.
channel.write(ByteBuffer.wrap("testLocalSocketClose\n".getBytes()));
channel.configureBlocking(false);
Selector selector = Selector.open();
LOG.fine("registering channel");
channel.register(selector, SelectionKey.OP_READ, channel);
LOG.fine("closing channel");
channel.close();
LOG.fine("waiting...");
int i = selector.select();
// this never happens (or it does very rarely)
LOG.fine("selector woke with " + i + " selected");I would have expected the selector to return the selection key of the dead channel. Given that it doesn't and this scenario is possible (channel closing just after a read operation but before another select is called - in separate threads obviously). How can we reliably detect/be informed that the channel has been closed?
(I saw somewhere someone mention adding the OP_WRITE to the key, I have tried this as well and it makes no difference).
Many Thanks.
Bob.May I suggest you look at your application and reassess; either it's wrong or it's your understanding of what our issue is.
Please try the simple test below.
WSADATA ws;
WSAStartup(0x0101, &ws);
SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(9000);
cout << "binding" << endl;
bind(sock, (struct sockaddr *)&server, sizeof(server));
cout << "listening" << endl;
listen(sock, SOMAXCONN);
struct sockaddr_in client;
int client_size = sizeof(client);
memset(&client, 0, client_size);
cout << "accepting" << endl;
SOCKET clientSock = accept(sock, (struct sockaddr*)&client, &client_size);
// shutdown socket.
cout << "shutting down client socket" << endl;
shutdown(clientSock, SD_BOTH);
// setup select
FD_SET fd;
TIMEVAL tv;
FD_ZERO(&fd);
tv.tv_sec = static_cast<int>(6000);
tv.tv_usec = 0;
FD_SET(clientSock, &fd);
cout << "selecting" << endl;
int rc = select(0, &fd, NULL, NULL, &tv);
cout << rc << ", " << FD_ISSET(clientSock, &fd) << endl;
char msg[500];
if (FD_ISSET(clientSock, &fd)) {
cout << recv(clientSock, msg, 500, 0) << endl;
cout << WSAGetLastError() << endl;
cout << "closing" << endl;
closesocket(clientSock);Telnet to port 9000, you get the following output immediately:
binding
listening
accepting
shutting down client socket
selecting
1, 1
-1
10058
closing
The solution I posted previously re calling shutdownInput/Output in Java isn't correct however, I left OP_WRITE on by mistake, which always returns ready, my fault. Apologies.
Whatever the behaviour, it will be the same for Selector.select() as it is for select().
Clearly not.
Edited by: Bawb on 29-Jul-2011 07:01, I had left OP_WRITE on which was returning ready each time, when I realised and took it out I removed the shutdown code which made me think I hadn't sorted this. Apologies again.
Still reckon an RFE for OP_SHUTDOWN should be added to Java.
Thanks. -
Hi all
I have an distributed application .I use jboss as a application server.I 've done a session bean that create a class containing a multi thread socket .I wonder if it's right does a multi thread socket or jboss does the multithreading by itself.
Regards
GioThere is no such thing as a multi thread socket. There are just sockets. How you use them is up to you.
-
IP of client in Server Socket Channel
how could we find the IP of clients in TCP\IP NIO Channel....
SocketChannel.socket().getInetAddress() on the accepted socket
-
Socket Channel Connection - Continuous read
Hi all,
I am new to socket programming. This is where I am stuck...I need to read from a channel 'continuously', i.e messages are continuous published and I need to keep on reading it. Below is my code for review....I am just getting the 1st line of the message. please suggest..Thanks in advance
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;
public class TestConnection {
private static Charset charset = Charset.forName("ISO-8859-1");
private static CharsetDecoder decoder = charset.newDecoder();
public static void main(String[] args) throws IOException {
SocketChannel sc = null;
String desthost = "172.19.67.33";
int port = 5002;
InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName(desthost), port);
try {
sc = SocketChannel.open();
sc.connect(isa);
System.out.println(" Message--> " + readFromChannel(sc, 4096));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sc != null)
sc.close();
public static String readFromChannel(SocketChannel sChannel, final int size) throws IOException {
int numBytes = 0;
boolean hasRead = false;
ByteBuffer inBuffer = ByteBuffer.allocateDirect(size);
CharBuffer charBuffer = CharBuffer.allocate(size + 100);
StringBuffer dataRead = new StringBuffer();
Selector selector = Selector.open();
System.out.println(" Is Connected--> " + sChannel.isConnected());
System.out.println(" sChannel.isBlocking()--> " + sChannel.isBlocking());
sChannel.configureBlocking(false);
System.out.println(" sChannel.isBlocking()--> " + sChannel.isBlocking());
sChannel.register(selector, SelectionKey.OP_READ);
try {
while (selector.select(20000) > 0) {
Set readyKeys = selector.selectedKeys();
Iterator readyItor = readyKeys.iterator();
while (readyItor.hasNext()) {
SelectionKey key = (SelectionKey) readyItor.next();
readyItor.remove();
ReadableByteChannel keyChannel = (SocketChannel) key.channel();
if (key.isReadable()) {
for (int i = 0;; i++) {
int count = 0;
if ((count = keyChannel.read(inBuffer)) < 0) // EOF
keyChannel.close();
throw new IOException("Socket lost connection during read operation");
numBytes += count;
if (!inBuffer.hasRemaining()) {
hasRead = true;
System.out.println("has read");
System.out.println("SUCCESSFUL, length of data read:" + numBytes);
inBuffer.flip();
decoder.decode(inBuffer, charBuffer, false);
charBuffer.flip();
selector.close();
return dataRead.append(charBuffer).toString();
if (i >= 2) {
break;
if (false == hasRead) {
System.err.println("has _NOT_ read");
System.err.println("length of data read: " + numBytes);
System.err.println("length of data read: " + numBytes);
if (numBytes > 0) {
inBuffer.flip();
decoder.decode(inBuffer, charBuffer, false);
charBuffer.flip();
System.err.println("ERROR, data read: " + dataRead.append(charBuffer).toString());
throw new IOException("Socket read operation timed out");
} else {
throw new IOException("Invalid Read Socket state");
} finally {
selector.close();
}The output is -->
Is Connected--> true
sChannel.isBlocking()--> true
sChannel.isBlocking()--> false
has read
SUCCESSFUL, length of data read:4096
Message--> 000c100000300000007f100700302E12008071104060400 Lane Communication Is OK 004d100500300302E0100000027000000000000000000000000000010845800000000000000000000000c100000302E01007f100700303E12008071104140200 Lane Communication Is OK 004d100500300303E0402350427000000000000000000000000000119107300000008500000000000000c100000303E00007f100700304E12008070704085600 Lane Communication Is OK 004d100500300304E0201521427000000000000000000000000000081090700000003640000000000000c100000304E00007f100700305X12008071104111600 Lane Communication Is OK 004d100500300305X0801411215000000000000000000000000000048892600000000810000000001000c100000305X00007f100700306X12008071104102600 Lane Communication Is OK 004d100500300306X0800660815000000000000000000000000000046838800000000760000000000000c100000306X00007f100700307X12008063003542200 Lane Communication Is OK 004d100500300307X1000445315000000000000000000000000000125509000000017220000000127000c100000307X000104100300300307X200807111727309311015004453030200000000000000000000000000000527000001020102000000001154210344501304E2008071116072500EZPASS TAG# 022 - 04522780 STATUS = VALID TYPE = INTERIOR FPT Program Status = Success 00012550910000001723000000012820104100300300305X200807111727325610815014112010200000000000000000000000000000000010201020102000000005146360015500121E2008071117010800MANUAL CASH IN EXIT MANUAL 00004889270000000082000000000100104100300300307X200807111727353911015004453030200000000000000000000000000000072000001020102000000001154220344700103E2008071117070600EZPASS TAG# 008 - 03623801 STATUS = VALID TYPE = INTERIOR FPT Program Status = Success 00012550920000001724000000012800104100300300307X200807111727379411015004453030200000000000000000000000000000072000001020102000000001154230344900401E2008071117181300EZPASS TAG# 006 - 00468916 STATUS = VALID TYPE = INTERIOR FPT Program Status = Success 00012550930000001725000000012800104100300300306X200807111727399610815006608010200000000000000000000000000000000010201020102000000000075910013300613E2008071117032500MANUAL
The out actually gives multiple line...but what should be the approach to read line by line continuously and keep parsing them......
kind regards -
client server java nonblocking SocketChannel
at the server do writes using this:
socketChannel.write(byteBuffer);
At the client end do a read
socketChannel.read(inBuffer);
When does the client read method return ?. Assume inBuffer is empty and is bigger than byteBuffer. Does it wait until it gets all of a single write or if there is an internet delay does it return with only part of the write bytes?
Can read return with only some of the bytes sent in a single write ?
The point am getting at is can inBuffer after a read have 2 partial write packets, or several write packets with perhaps partial packets at the start and end ?
thanks
p butlerWith TCP/IP read() can return any number of bytes from 1 to the size of the buffer (also 0 bytes if you have a non-blocking socket). The sending operating system, the receiving operating system, and all routers/firewalls/etc in between can break up and/or combine writes any way they want to. TCP is a stream protocol, not a packet protocol; "packet" or write() boundaries are not preserved.
There are a couple of common ways to send "packets":
A line based protocol. Each "packet" is a single line of text. If the actual payload data can contain \r or \n characters, those need to be escaped with a suitable escape character. Other packet terminators can be used also. e.g. "\n.\n" (= a period on a line of its own.)
Length+data. Before sending a "packet", send an e.g. 4-byte value that tells how long the packet is. In the receiver, read until you have that many bytes. Note that even the 4-byte length header can be split up so that you may need to do four read() calls to get them all! DataInputStream has a readFully() method, or you can write your own static utility; see reply 5 here: http://forum.java.sun.com/thread.jspa?threadID=677542 -
Hello
Anybody, whose been working with the new J2SE 1.4 ... i have a question i was just glancing at the New I/O functionalities and its speaks pretty strongly about having SocketChannels, but i really couldnt make out any greater advantage it has over the Socket connections in J2SE 1.3.1.x ...
Infact it seemed more overhead and operations when the ur still in the end reading and writing to the socket ... what superiority does a SocketChannel provide over its predecessor the Socket connection in terms of efficiency, socket queueing and its TCP capabilities.A SocketChannel as I see it, gives you access to both read and write with the same object, and you use a ByteBuffer when you want to read and write (the idea is to avoid garbage collection). There is a good resource here:
http://www.javaworld.com/javaworld/jw-09-2001/jw-0907-merlin_p.html
With the Selector, you don't need to create a new thread for each connection to your server, just one for each server should be enough (or maybe two, one that listens for connections, and one that notifies you when there are channels ready to be read from).
The link above explains it quite well I think (with the lack of other resources about the nio packages). -
Hi,
I have a appication uses ServerSocketChannel at the server side and socket at the client side. I am using selector to read the requests that comes to the server. And I am using three ports, each for a separate operation. One such port is meant for streaming purpose. That is when the client requests foe a particular stream from IP Camera, the server gets the requests and gives streams in response.
My problem is that, when I connect more than one camera, I gets streams intermixed. The streams are intermixed only when using a high speed network. How can I find a solution to this problem.
ThanksHow can I find a solution to this problem. As a start, you might want to post to a more appropriate forum, such as
http://forum.java.sun.com/forum.jspa?forumID=11 -
Do I need to cancel the selection key when I close it's socket channel?
I have a non blocking server implementation and I need to know is it mandatory to call SelectionKey#cancel after I have called the SocketChannel#close to it's channel? When I close the channel, will it cancel the key automatically or what if I don't cancel the key, how does it affect to the selector?
JKThanks ejp, you are right, it's documented in SelectableChannel not in SocketChannel. My mistake.
-
Edit volume of multi-track stereo channels separately?
Subject says it all, I want to have a separate volume curve for R/L channel in a single track - what's the best way?
Thanks.If it wants to be variable throughout the file, then split the stereo out to mono, put in in multitrack view on two separate tracks, and use the volume envelope automation lanes. If you still want it as stereo afterwards, then pan each track left and right as appropriate, and do a stereo mixdown/export.
-
Problem with writing to a socket channel
My situation is thus:
I have a SocketChannel connected to a remote telnet server. I am using a keylistener to listen for the enter button on a jtextarea in order to send the contents of that jtextarea to the remote telnet server via socketchannel.write
The problem is that when I have the code to do this located in a keyReleased event listener, it works fine. However, for other reasons, I really need it to be in a keyPressed event listener, and it fails silently when I put it in one.
I have code both before and after the part of the listener that calls socketchannel.write that executes properly, and some debug code that shows that i am sending the bytes that I think that I'm sending, and the socketchannel.write call returns the correct integer to agree with the number of bytes I'm trying to send, but the remote server never actually receives those bytes. It would automatically send back a response if it did, and even beyond that, I get timed out for inactivity by the remote server even if i continuously hit enter to send data.
The keylistener i'm using is a class extended from keyadapter. I can literally flip the function signature back and forth between keyReleased and keyPressed, and it works absolutely perfectly with keyReleased, and everything but the socketchannel.write works perfectly with keyPressed. I am at a complete loss as to why it works with one, and not with the other.
Any insights?
Thanks in advance.I have found an answer elsewhere.
The problem was that, with keyReleased, the actual stroke of the enter key was being recorded before the text was being sent, so it had a \n on the end of it.
The game required a terminator in order to be able to process the data I sent, and keyPressed wasn't generating one. -
Flush() in Asynchronous NIO Channels
I wrote an asynchronous client-server socket implementation based fully on NIO Channels. My implementation does include old Socket or ServerSocket classes, I used only SocketChannel and ServerSocketChannel classes, with ByteBuffer's to send/receive data on non-blocking channel mode.
Everything looks very comfortable except one thing, looks like old FLUSH() method from OutputStream is still required in NIO. My small write requests (3 bytes length) does not reach the destination. I call write() several times but the read() doesn't get any data. So it looks like I need a flush for Channel, but Channel class don't have any flush() method.
I tried two solutions to solve this situation and FAILED:
1-) In Channels class there are newInputStream() and newOutputStream() methods to get InputStream and OutputStream's of ByteChannels. I used OutputStream's flush() method, but as you guess non-blocking mode does not let you to use write/read methods since they are in blocking mode, but my channels are in non-blocking mode. So I failed here.
2) I watched the actual data transmitted from TCP stack using Ethereal, what I see is my packets are send to the destination address SUCCESSFULLY. The problem looks like the receiver side does not take them immediately. I decreased the size of ByteBuffer used in read() at the receiver but nothing changed.
The point is my packets are still not readable from the destination address.Well, NIO implementation looks different from Stream
implementation for sockets. I solved my problem by
decreasing the buffer size at the receiver side.
Sometimes read() of socket channel returns completely
filled and sometimes with half filled data. I can not
distinguish which one will come but at this point it
is enoughfor me...Yes, but my intent was simply to determine whether the data is receivable at all. However, you've now determined that it is.
In your place I would not be comfortable with the situation that now pertains. The mere fact that reducing the buffer size seems to make it work in your testing environment is hardly a demonstration that it works 100% of the time, nor that it will work properly in production. You need to be able to explain why the change works, and why the code fails with the larger buffer size.
Sylvia -
If you have a connection to on a non-blocking socket channel will the socket, is it possible that it will stop streaming all the data available into the buffer? If so how can you check that this has happened?
If you buffer being used by the socket is full how can make sure the streaming stops so you can drain the buffer and get the remaining data without losing it from the channel.
How can you check to see if a channel has no more data to give?
Thank you.The sender's write method will block in blocking mode, or return zero in non-blocking mode, when the target's receive buffer and the sender's send buffer are both full. This is the only flow control available unless you implement something yourself. The only way to tell whether you have read everything the other end is sending is by getting an EOF when the other end closes the socket, unless you build something into your application protocol.
Maybe you are looking for
-
Hello, I am checking the version i have installed of flash player via the adobe version check option at the site and i have version 11.8.800.94 and when i check the list of the latest versions of Adobe, i see 11.7.700.169 listed as being the latest v
-
Automatic Creation of BP(Credit Management Role) from Customer Master
We have done the required config for this. But the Business Partner is not getting created automatically when the customer is created. Rather, we have to run the synchronization cockpit. Is this the normal way (schedule a background job for Synchroni
-
What's the maximum number of bookmarks the Library can hold?
I want to bring all my bookmarks together into one place, preferably the Firefox Library function. Will it hold 3,000? 5,000? With those quantities, will it still retrieve them quickly? Any problems with this many bookmarks? Thanks to all.
-
Tried to Export a video in mp4 but it always gives me an error
Exporting mp4 used to not have errors but everytime I export it, it says there was an error and could not be important and this only happens when the imovie project is in mp4. How can I fix it?
-
Ive had my iphone for about a year now and the home button slowly started to not work. Now i have to press it a couple of times to get it to work. It feels normal, its not loose and i hardly ever drop it