📄 sharedsocket.java
字号:
sslSocket.close();
sslSocket = null;
setOut(new DataOutputStream(socket.getOutputStream()));
setIn(new DataInputStream(socket.getInputStream()));
}
/**
* Set the character set descriptor to be used to translate byte arrays to
* or from Strings.
*
* @param charsetInfo the character set descriptor
*/
void setCharsetInfo(CharsetInfo charsetInfo) {
this.charsetInfo = charsetInfo;
}
/**
* Retrieve the character set descriptor used to translate byte arrays to
* or from Strings.
*/
CharsetInfo getCharsetInfo() {
return charsetInfo;
}
/**
* Retrieve the character set name used to translate byte arrays to
* or from Strings.
*
* @return the character set name as a <code>String</code>
*/
String getCharset() {
return charsetInfo.getCharset();
}
/**
* Obtain an instance of a server request stream for this socket.
*
* @param bufferSize the initial buffer size to be used by the
* <code>RequestStream</code>
* @param maxPrecision the maximum precision for numeric/decimal types
* @return the server request stream as a <code>RequestStream</code>
*/
RequestStream getRequestStream(int bufferSize, int maxPrecision) {
synchronized (socketTable) {
int id;
for (id = 0; id < socketTable.size(); id++) {
if (socketTable.get(id) == null) {
break;
}
}
VirtualSocket vsock = new VirtualSocket(id);
if (id >= socketTable.size()) {
socketTable.add(vsock);
} else {
socketTable.set(id, vsock);
}
return new RequestStream(this, id, bufferSize, maxPrecision);
}
}
/**
* Obtain an instance of a server response stream for this socket.
* NB. getRequestStream() must be used first to obtain the RequestStream
* needed as a parameter for this method.
*
* @param requestStream an existing server request stream object obtained
* from this <code>SharedSocket</code>
* @param bufferSize the initial buffer size to be used by the
* <code>RequestStream</code>
* @return the server response stream as a <code>ResponseStream</code>
*/
ResponseStream getResponseStream(RequestStream requestStream, int bufferSize) {
return new ResponseStream(this, requestStream.getStreamId(), bufferSize);
}
/**
* Retrieve the TDS version that is active on the connection
* supported by this socket.
*
* @return the TDS version as an <code>int</code>
*/
int getTdsVersion() {
return tdsVersion;
}
/**
* Set the TDS version field.
*
* @param tdsVersion the TDS version as an <code>int</code>
*/
protected void setTdsVersion(int tdsVersion) {
this.tdsVersion = tdsVersion;
}
/**
* Set the global buffer memory limit for all instances of this driver.
*
* @param memoryBudget the global memory budget
*/
static void setMemoryBudget(int memoryBudget) {
SharedSocket.memoryBudget = memoryBudget;
}
/**
* Get the global buffer memory limit for all instancs of this driver.
*
* @return the memory limit as an <code>int</code>
*/
static int getMemoryBudget() {
return SharedSocket.memoryBudget;
}
/**
* Set the minimum number of packets to cache in memory before
* writing to disk.
*
* @param minMemPkts the minimum number of packets to cache
*/
static void setMinMemPkts(int minMemPkts) {
SharedSocket.minMemPkts = minMemPkts;
}
/**
* Get the minimum number of memory cached packets.
*
* @return minimum memory packets as an <code>int</code>
*/
static int getMinMemPkts() {
return SharedSocket.minMemPkts;
}
/**
* Get the connected status of this socket.
*
* @return <code>true</code> if the underlying socket is connected
*/
boolean isConnected() {
return this.socket != null;
}
/**
* Send a TDS cancel packet to the server.
*
* @param streamId the <code>RequestStream</code> id
* @return <code>boolean</code> true if a cancel is actually
* issued by this method call.
*/
boolean cancel(int streamId) {
//
// Need to synchronize packet send to avoid race conditions on
// responsOwner and cancelPending
//
synchronized (cancelMonitor) {
//
// Only send if response pending for the caller.
// Caller must have aquired connection mutex first.
// NB. This method will not work with local named pipes
// as this thread will be blocked in the write until the
// reading thread has returned from the read.
//
if (responseOwner == streamId && !cancelPending) {
try {
//
// Send a cancel packet.
//
cancelPending = true;
byte[] cancel = new byte[TDS_HDR_LEN];
cancel[0] = TdsCore.CANCEL_PKT;
cancel[1] = 1;
cancel[2] = 0;
cancel[3] = 8;
cancel[4] = 0;
cancel[5] = 0;
cancel[6] = (tdsVersion >= Driver.TDS70) ? (byte) 1 : 0;
cancel[7] = 0;
getOut().write(cancel, 0, TDS_HDR_LEN);
getOut().flush();
if (Logger.isActive()) {
Logger.logPacket(streamId, false, cancel);
}
return true;
} catch (IOException e) {
// Ignore error as network is probably dead anyway
}
}
}
return false;
}
/**
* Close the socket and release all resources.
*
* @throws IOException if the socket close fails
*/
void close() throws IOException {
if (Logger.isActive()) {
Logger.println("TdsSocket: Max buffer memory used = " + (peakMemUsage / 1024) + "KB");
}
synchronized (socketTable) {
// See if any temporary files need deleting
for (int i = 0; i < socketTable.size(); i++) {
VirtualSocket vsock = (VirtualSocket) socketTable.get(i);
if (vsock != null && vsock.diskQueue != null) {
try {
vsock.diskQueue.close();
vsock.queueFile.delete();
} catch (IOException ioe) {
// Ignore errors
}
}
}
try {
if (sslSocket != null) {
sslSocket.close();
sslSocket = null;
}
} finally {
// Close physical socket
if (socket != null) {
socket.close();
}
}
}
}
/**
* Force close the socket causing any pending reads/writes to fail.
* <p>
* Used by the login timer to abort a login attempt.
*/
void forceClose() {
if (socket != null) {
try {
socket.close();
} catch (IOException ioe) {
// Ignore
} finally {
sslSocket = null;
socket = null;
}
}
}
/**
* Deallocate a stream linked to this socket.
*
* @param streamId the <code>ResponseStream</code> id
*/
void closeStream(int streamId) {
synchronized (socketTable) {
VirtualSocket vsock = lookup(streamId);
if (vsock.diskQueue != null) {
try {
vsock.diskQueue.close();
vsock.queueFile.delete();
} catch (IOException ioe) {
// Ignore errors
}
}
socketTable.set(streamId, null);
}
}
/**
* Send a network packet. If output for another virtual socket is
* in progress this packet will be sent later.
*
* @param streamId the originating <code>RequestStream</code> object
* @param buffer the data to send
* @return the same buffer received if emptied or another buffer w/ the
* same size if the incoming buffer is cached (to avoid copying)
* @throws IOException if an I/O error occurs
*/
byte[] sendNetPacket(int streamId, byte buffer[])
throws IOException {
synchronized (socketTable) {
VirtualSocket vsock = lookup(streamId);
while (vsock.inputPkts > 0) {
//
// There is unread data in the input buffers.
// As we are sending another packet we can just discard it now.
//
if (Logger.isActive()) {
Logger.println("TdsSocket: Unread data in input packet queue");
}
dequeueInput(vsock);
}
if (responseOwner != -1) {
//
// Complex case there is another stream's data in the network pipe
// or we had our own incomplete request to discard first
// Read and store other stream's data or flush our own.
//
VirtualSocket other = (VirtualSocket)socketTable.get(responseOwner);
byte[] tmpBuf = null;
boolean ourData = (other.owner == streamId);
do {
// Reuse the buffer if it's our data; we don't need it
tmpBuf = readPacket(ourData ? tmpBuf : null);
if (!ourData) {
// We need to save this input as it belongs to
// Another thread.
enqueueInput(other, tmpBuf);
} // Any of our input is discarded.
} while (tmpBuf[1] == 0); // Read all data to complete TDS packet
}
//
// At this point we know that we are able to send the first
// or subsequent packet of a new request.
//
getOut().write(buffer, 0, getPktLen(buffer));
if (buffer[1] != 0) {
getOut().flush();
// We are the response owner now
responseOwner = streamId;
}
return buffer;
}
}
/**
* Get a network packet. This may be read from the network directly or from
* previously cached buffers.
*
* @param streamId the originating ResponseStream object
* @param buffer the data buffer to receive the object (may be replaced)
* @return the data in a <code>byte[]</code> buffer
* @throws IOException if an I/O error occurs
*/
byte[] getNetPacket(int streamId, byte buffer[]) throws IOException {
synchronized (socketTable) {
VirtualSocket vsock = lookup(streamId);
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -