📄 tcpipconnection.java
字号:
throws IOException { debug.enter(DCOM,this,"close"); IOException exception = null; if (connType == CONN_CLIENT) { try { inputStream.close(); outputStream.close(); socket.close(); socket = null; opened = false; debug.write(DCOM,"closed client tcp/ip connection to "+address+ " on port "+port); } catch (IOException e) { debug.write("IOException closing socket " + e); event.write(e,"IOException closing socket"); exception = e; } } else if (connType == CONN_SERVER) { try { receiverSocket.close(); receiverSocket = null; opened = false; debug.write(DCOM,"stopped listening tcp/ip on port "+port); } catch (IOException e) { debug.write("IOException closing listener socket " + e); event.write(e,"IOException closing listener socket"); exception = e; } } else { debug.write("Unknown connection type = " + connType); } debug.exit(DCOM,this); if (exception != null) { throw exception; } } /** * Sends data over the connection. Must be client type connection. * The timeout for sending is set by <code>setCommsTimeout</code>. * * @see java.net.Socket */ public void send(ByteBuffer data) throws IOException { debug.enter(DCOM,this,"send"); IOException exception = null; if (connType == CONN_CLIENT) { try { socket.setSoTimeout((int)getCommsTimeout()); try { outputStream.write(data.getBuffer(), 0, data.length()); debug.write(DCOM,"sent "+data.length()+" bytes to "+address+ " on port "+port); } catch (IOException e) { debug.write("IOException sending data " + e); exception = e; } outputStream.flush(); } catch (IOException e) { debug.write("IOException flushing data " + e); if (exception == null) { exception = e; } } } else if (connType == CONN_SERVER) { debug.write("Attempt to send data over server type connection."); } else { debug.write("Unknown connection type = " + connType); } debug.exit(DCOM,this); if (exception != null) { throw exception; } } /** * Reads data from the connection. Must be client type connection. * The timeout for receiving is set by <code>setReceiveTimeout</code>. * The timeout for single attempt to read something from socket is * set by <code>setCommsTimeout</code>. * * @see #setReceiveBufferSize(int) * @see #setMaxReceiveSize(int) * @see Connection#getCommsTimeout() * @see java.net.Socket */ public ByteBuffer receive() throws IOException { debug.enter(DCOMD,this,"receive"); IOException exception = null; ByteBuffer data = null; if (connType == CONN_CLIENT) { data = new ByteBuffer(); long endTime = Data.getCurrentTime() + getReceiveTimeout(); //int bytesAvailable = 0; int bytesToRead = 0; int bytesRead = 0; int totalBytesRead = 0; try { socket.setSoTimeout((int)getCommsTimeout()); bytesToRead = receiveBufferSize; debug.write(DCOMD,"going to read from socket"); debug.write(DCOMD,"comms timeout="+getCommsTimeout()+ " receive timeout="+getReceiveTimeout()+ " receive buffer size="+receiveBufferSize); do { bytesRead = 0; try { bytesRead = inputStream.read(receiveBuffer, 0, bytesToRead); } catch (InterruptedIOException e) { // comms read timeout expired, no problem debug.write(DCOMD,"timeout reading from socket"); } // http://www.smsforum.net/yabbse/index.php?board=7;action=display;threadid=298 // it seems like it is assumed inputStream.read will alwasy return a non-negative // when a connection is closed by SMSC the return value will be -1 which causes // an endless loop // the fix consists of checking the value to be -1 and if true throwing an IOException if( bytesRead == -1){ try { inputStream.close(); } catch (IOException e) {} debug.write("connection closed by smsc."); throw new IOException("Connection was closed by SMSC."); } if (bytesRead > 0) { debug.write(DCOMD,"read "+bytesRead+" bytes from socket"); data.appendBytes(receiveBuffer,bytesRead); totalBytesRead += bytesRead; } bytesToRead = inputStream.available(); if (bytesToRead>0) { debug.write(DCOMD,"more data ("+bytesToRead+" bytes) remains in the socket"); } else { debug.write(DCOMD,"no more data remains in the socket"); } if (bytesToRead > receiveBufferSize) { bytesToRead = receiveBufferSize; } if (totalBytesRead+bytesToRead > maxReceiveSize) { // would be more than allowed bytesToRead = maxReceiveSize - totalBytesRead; } } while (((bytesToRead!=0) && (Data.getCurrentTime()<=endTime)) && (totalBytesRead < maxReceiveSize)); debug.write(DCOM,"totally read "+data.length()+" bytes from socket"); } catch (IOException e) { debug.write("IOException " + e); event.write(e,"IOException receive via TCPIPConnection"); exception = e; } } else if (connType == CONN_SERVER) { debug.write("Attempt to receive data from server type connection."); } else { debug.write("Unknown connection type = " + connType); } debug.exit(DCOMD,this); if (exception != null) { throw exception; } return data; } /** * Accepts new connection on server type connection, i.e. on ServerSocket. * If new socket is returned from ServerSocket.accept(), creates new * instance of TCPIPConnection with the new socket and returns it, * otherwise returns null. The timeout for new connection accept is * set by <code>setReceiveTimeout</code>, i.e. waits for new connection * for this time and then, if none is requested, returns with null. * * @see #TCPIPConnection(Socket) * @see java.net.ServerSocket#accept() * @see java.net.ServerSocket#setSoTimeout(int) */ public Connection accept() throws IOException { debug.enter(DCOMD,this,"receive"); IOException exception = null; Connection newConn = null; if (connType == CONN_SERVER) { try { receiverSocket.setSoTimeout((int)getReceiveTimeout()); } catch (SocketException e) { // don't care, we're just setting the timeout } Socket acceptedSocket = null; try { acceptedSocket = receiverSocket.accept(); } catch (IOException e) { debug.write(DCOMD,"Exception accepting socket (timeout?)" + e); } if (acceptedSocket != null) { try { newConn = new TCPIPConnection(acceptedSocket); } catch (IOException e) { debug.write("IOException creating new client connection "+e); event.write(e,"IOException creating new client connection"); exception = e; } } } else if (connType == CONN_CLIENT) { debug.write("Attempt to receive data from client type connection."); } else { debug.write("Unknown connection type = " + connType); } debug.exit(DCOMD,this); if (exception != null) { throw exception; } return newConn; } /** * Initialises input and output streams to the streams from socket * for client type connection. * Streams are used for sending and receiving data from the socket. * * @see #inputStream * @see #outputStream * @see java.net.Socket#getInputStream() * @see java.net.Socket#getOutputStream() */ private void initialiseIOStreams(Socket socket) throws IOException { if (connType == CONN_CLIENT) { inputStream = new BufferedInputStream(socket.getInputStream(), ioBufferSize); outputStream = new BufferedOutputStream(socket.getOutputStream(), ioBufferSize); } else if (connType == CONN_SERVER) { debug.write("Attempt to initialise i/o streams for server type connection."); } else { debug.write("Unknown connection type = " + connType); } } /** * Sets the size for the io buffers of streams for accessing the socket. * The size can only be changed before actual opening of the connection. * @see #initialiseIOStreams(Socket) */ public void setIOBufferSize(int ioBufferSize) { if (!opened) { this.ioBufferSize = ioBufferSize; } } /** * Sets the size of the receiving buffer, which is used for reading from * the socket. A buffer of this size is allocated for the reading. * @see #receive() */ public void setReceiveBufferSize(int receiveBufferSize) { this.receiveBufferSize = receiveBufferSize; receiveBuffer = new byte[receiveBufferSize]; } /** * Sets the maximum size of the data which can be read in one call to * the <code>receive</code> function. After reading of this amount * of bytes the receive returns the data read even if there are more data * in the socket. * @see #receive() */ public void setMaxReceiveSize(int maxReceiveSize) { this.maxReceiveSize = maxReceiveSize; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -