1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
Ici c'est le code writeToSocketde l'instance fSendMessagesManager (instance d'une inner class)
/**
* write data from socket, serialize all messages.
*
* @return true if the socket is full and some elements need to be send later, false if no more element to send.
* @throws IOException
*/
public boolean writeToSocket(SelectionKey aKey) throws IOException
{
int iNbMessagesToSend;
do
{
synchronized(m_lstMessagesToSend)
{ // Protect concurent access to m_lstMessagesToSend
iNbMessagesToSend = m_lstMessagesToSend.size();
if (flLengthMessage == 0 && iNbMessagesToSend>0)
{
ISerializationObject iMessage;
// Remove first element of the list
Iterator<ISerializationObject> it = m_lstMessagesToSend.iterator();
iMessage = it.next();
it.remove();
--iNbMessagesToSend;
// Serialize this message and add if after previous one if exists
int iCurrentPosition = fReadWriteBuffer.position(); // Record current position
fReadWriteBuffer.position(iCurrentPosition + 4); // Left space for message size
SerializationArchive ar = new SerializationArchive(SerializationArchive.SensArchive.Storing,fReadWriteBuffer);
ar.WriteObject(iMessage); // Serialize message
flLengthMessage = fReadWriteBuffer.position() - iCurrentPosition;
fReadWriteBuffer.putInt(iCurrentPosition,(int) flLengthMessage - 4); // Write message size before the serialized element
fReadWriteBuffer.flip();
}
}
if (flLengthMessage > 0)
{ // Something to write
SocketChannel socketChannel = (SocketChannel) aKey.channel();
// Write message content
int iNbBytesWrites = socketChannel.write(fReadWriteBuffer);
flLengthMessage -= iNbBytesWrites;
if (flLengthMessage == 0)
{ // If all is send, compact and prepare to send next
fReadWriteBuffer.compact(); // Suppress this message, ready to reading next one
}
else
{
int h= 0;
h++;
}
}
} // Continuer tant qu'il y a de la place et qu'il y a des messages en attente dans la file d'attente
while (flLengthMessage==0 && iNbMessagesToSend>0);
return flLengthMessage!=0 || iNbMessagesToSend>0;
}
FIN de Ici c'est le code writeToSocketde l'instance fSendMessagesManager (instance d'une inner class)
/**
* Write data from socket, serialize if needed.
*
* Write to socket next content to send.
*
* @param aKey Key to manage.
* @throws IOException
*/
private void writeToSocket(SelectionKey aKey) throws IOException
{
if (fSendMessagesManager.writeToSocket(aKey))
{ // More elements to write
aKey.interestOps(aKey.interestOps() | SelectionKey.OP_WRITE);
}
else
{ // No more elements to write
aKey.interestOps(aKey.interestOps() & ~SelectionKey.OP_WRITE);
}
}
private void processSelectionKey(SelectionKey selKey) throws Exception
{
if (!selKey.isValid())
{ // Disconnected socket
throw new IOException();
}
else
{
// Since the ready operations are cumulative,
// need to check readiness for each operation
if (selKey.isConnectable())
{
// Get channel with connection request
SocketChannel sChannel = (SocketChannel) selKey.channel();
try
{
if (sChannel.finishConnect())
{
selKey.interestOps(selKey.interestOps() & ~SelectionKey.OP_CONNECT);
selKey.interestOps(selKey.interestOps() | SelectionKey.OP_READ);
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
onSocketConnect();
}
});
}
}
catch(IOException ex)
{ // An error occurred : cannot connect : notify disconnection
throw new SocketDisconnectedException();
}
}
if (selKey.isReadable())
{
readFromSocketAndNotify(selKey);
}
if (selKey.isWritable())
{
writeToSocket(selKey);
}
}
}
/**
* Initialize the socket.
*
* Used when socket is accepted, to give socket to managers.
* Made automatically on client side on QTSOCKET_CONNECTION event,
* must be done manually on server side after the accept command.
*
* @param _pSocket Pointer on socket. Should be valid.
* @param _bDeleteWhenDisconnect Indicate if the socket should be deleted after disconnect.
*/
public void init(SocketChannel aSocket)
{
clear();
try
{
configureChannel(aSocket);
fSelector = Selector.open();
aSocket.register(fSelector, SelectionKey.OP_CONNECT);
Thread thread = new Thread(new Runnable()
{
@Override public void run()
{
SelectionKey selKey = null;
try
{
while (true)
{
// Wait for an event
fSelector.select();
// Get list of selection keys with pending events
@SuppressWarnings("rawtypes")
Iterator it = fSelector.selectedKeys().iterator();
// Process each key at a time
while (it.hasNext())
{
// Get the selection key
selKey = (SelectionKey) it.next();
// Remove it from the list to indicate that it is being
// processed
it.remove();
// If is connected or will be connected
processSelectionKey(selKey);
selKey = null;
}
}
}
catch(SocketDisconnectedException e)
{
if (selKey != null)
{ // Handle error with channel and unregister
selKey.cancel();
}
try
{
fTCPSocket.close();
}
catch (IOException ex)
{ // Don't care if exception is raised
}
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
onSocketDisconnect();
}
});
}
catch (Exception e)
{
if (selKey != null)
{ // Handle error with channel and unregister
selKey.cancel();
}
}
finally
{
clear();
}
}
}); // Wait for events
fTCPSocket = aSocket;
thread.start(); // Start the thread
}
catch (IOException e)
{
e.printStackTrace();
}
} |
Partager