📄 sockssocketimpl.java
字号:
/*
* instance variable for SO_LINGER
*/
private int soLinger=-1;
/*
* instance variable for SO_SNDBUF
*/
private int soSndBuf=0;
/*
* instance variable for SO_SNDBUF
*/
private int soRCVndBuf=0;
/**
* Sets the maximum queue length for incoming connection indications
* (a request to connect) to the <code>count</code> argument. If a
* connection indication arrives when the queue is full, the
* connection is refused.
*
* @param backlog the maximum length of the queue.
* @exception IOException if an I/O error occurs when creating the queue.
*/
protected synchronized void listen(int backlog) throws IOException
{
}
/**
* Accepts a connection.
*
* @param s the accepted connection.
* @exception IOException if an I/O error occurs when accepting the
* connection.
*/
protected synchronized void accept(SocketImpl s) throws IOException
{
}
/**
* Returns the address and port of this socket as a <code>String</code>.
*
* @return a string representation of this socket.
*/
public String toString()
{
return "SocksSocket[addr=" + getInetAddress() +
",port=" + getPort() +
",localaddr="
+(getLocalAddress()!=null?getLocalAddress().toString():"127.0.0.1")
+",localport=" + getLocalPort()
+(getProxyAddress()!=null?
",proxyddr=" + getProxyAddress() +
",proxyport=" + getProxyPort():"")
+"]";
}
/**
* Cleans up if the user forgets to close it.
*/
protected void finalize() throws IOException
{
close();
}
/**
* Fetch the value of an option.
* Binary options will return java.lang.Boolean(true)
* if enabled, java.lang.Boolean(false) if disabled, e.g.:
* <BR><PRE>
* SocketImpl s;
* ...
* Boolean noDelay = (Boolean)(s.getOption(TCP_NODELAY));
* if (noDelay.booleanValue()) {
* // true if TCP_NODELAY is enabled...
* ...
* }
* </PRE>
* <P>
* For options that take a particular type as a parameter,
* getOption(int) will return the paramter's value, else
* it will return java.lang.Boolean(false):
* <PRE>
* Object o = s.getOption(SO_LINGER);
* if (o instanceof Integer) {
* System.out.print("Linger time is " + ((Integer)o).intValue());
* } else {
* // the true type of o is java.lang.Boolean(false);
* }
* </PRE>
*
* @throws SocketException if the socket is closed
* @throws SocketException if <I>optID</I> is unknown along the
* protocol stack (including the SocketImpl)
*/
public Object getOption(int opt) throws SocketException
{
switch (opt)
{
case SO_TIMEOUT:
if(clientSocket!=null)
timeout=clientSocket.getSoTimeout();
return new Integer(timeout);
case TCP_NODELAY:
if(clientSocket!=null)
tcpNoDelay=clientSocket.getTcpNoDelay();
return new Boolean(tcpNoDelay);
case SO_LINGER:
if(clientSocket!=null)
soLinger=clientSocket.getSoLinger();
return new Integer(soLinger);
case SO_BINDADDR:
return localAddress;
case SO_SNDBUF:
if(clientSocket!=null)
soSndBuf=clientSocket.getSendBufferSize();
return new Integer(soSndBuf);
case SO_RCVBUF:
if(clientSocket!=null)
soRCVndBuf=clientSocket.getReceiveBufferSize();
return new Integer(soRCVndBuf);
case IP_MULTICAST_IF://For datagram socket
default:
throw new SocketException("unrecognized TCP option: " + opt);
}
}
/**
* Enable/disable the option specified by <I>optID</I>. If the option
* is to be enabled, and it takes an option-specific "value", this is
* passed in <I>value</I>. The actual type of value is option-specific,
* and it is an error to pass something that isn't of the expected type:
* <BR><PRE>
* SocketImpl s;
* ...
* s.setOption(SO_LINGER, new Integer(10));
* // OK - set SO_LINGER w/ timeout of 10 sec.
* s.setOption(SO_LINGER, new Double(10));
* // ERROR - expects java.lang.Integer
*</PRE>
* If the requested option is binary, it can be set using this method by
* a java.lang.Boolean:
* <BR><PRE>
* s.setOption(TCP_NODELAY, new Boolean(true));
* // OK - enables TCP_NODELAY, a binary option
* </PRE>
* <BR>
* Any option can be disabled using this method with a Boolean(false):
* <BR><PRE>
* s.setOption(TCP_NODELAY, new Boolean(false));
* // OK - disables TCP_NODELAY
* s.setOption(SO_LINGER, new Boolean(false));
* // OK - disables SO_LINGER
* </PRE>
* <BR>
* For an option that requires a particular parameter,
* setting its value to anything other than
* <I>Boolean(false)</I> implicitly enables it.
* <BR>
* Throws SocketException if the option is unrecognized,
* the socket is closed, or some low-level error occurred
* <BR>
* @param optID identifies the option
* @param value the parameter of the socket option
* @throws SocketException if the option is unrecognized,
* the socket is closed, or some low-level error occurred
*/public void setOption(int opt, Object val) throws SocketException
{
boolean flag = true;
switch (opt)
{
case SO_LINGER:
if (val == null || (!(val instanceof Integer) && !(val instanceof Boolean)))
throw new SocketException("Bad parameter for option");
if (val instanceof Boolean)
{
/* true only if disabling - enabling should be Integer */
flag = false;
}
if(clientSocket!=null)
{
if(flag)
soLinger=((Integer)val).intValue();
else
soLinger=clientSocket.getSoLinger();
clientSocket.setSoLinger(flag,soLinger);
}
break;
case SO_TIMEOUT:
if (val == null || (!(val instanceof Integer)))
throw new SocketException("Bad parameter for SO_TIMEOUT");
int t = ((Integer) val).intValue();
timeout=(t<0)?0:t;
if(clientSocket!=null)
clientSocket.setSoTimeout(timeout);
return;
case SO_BINDADDR:
throw new SocketException("Cannot re-bind socket");
case TCP_NODELAY:
if (val == null || !(val instanceof Boolean))
throw new SocketException("bad parameter for TCP_NODELAY");
flag = ((Boolean)val).booleanValue();
tcpNoDelay=flag;
if(clientSocket!=null)
clientSocket.setTcpNoDelay(tcpNoDelay);
break;
case SO_SNDBUF:
case SO_RCVBUF:
if (val == null || !(val instanceof Integer) ||
!(((Integer)val).intValue() > 0))
{
throw new SocketException("bad parameter for SO_SNDBUF " +
"or SO_RCVBUF");
}
if(clientSocket!=null)
{
int size=((Integer)val).intValue();
if(opt==SO_SNDBUF)
{
soSndBuf=size;
clientSocket.setSendBufferSize(size);
}
else
{
soRCVndBuf=size;
clientSocket.setReceiveBufferSize(size);
}
}
break;
case SO_REUSEADDR://For datagram socket
if (val== null || !(val instanceof Integer))
throw new SocketException("bad argument for SO_REUSEADDR");
// break;
case IP_MULTICAST_IF://For datagram socket
if(val == null || !(val instanceof InetAddress))
throw new SocketException("bad argument for IP_MULTICAST_IF");
// break;
default:
throw new SocketException("unrecognized TCP option: " + opt);
}
}
//The methods of DatagramSocketImpl
/**
* Creates a datagram socket
*/
protected void create() throws SocketException
{
//Nothing
}
/**
* Binds a datagram socket to a local port and address.
*/
protected void bind(int localport, InetAddress localAddress) throws SocketException
{
this.localAddress=localAddress;
this.localport=localport;
}
/**
* Sends a datagram packet from this socket. The
* <code>DatagramPacket</code> includes information indicating the
* data to be sent, its length, the IP address of the remote host,
* and the port number on the remote host.
*
* @param p the <code>DatagramPacket</code> to be sent.
*
* @exception IOException if an I/O error occurs.
*/
protected void send(DatagramPacket p) throws IOException
{
InetAddress packetAddress = p.getAddress();
if(address== null && packetAddress == null)
throw new IllegalArgumentException("Both of remote address and packet address are null.");
else if(packetAddress != null &&
!(packetAddress.equals(address) &&
p.getPort() == port))
{
connect(packetAddress,p.getPort());
}
else if(clientDatagramSocket==null)
connect(address,port);
if(proxyAddress==null)
{
clientDatagramSocket.send(p);
return;
}
//encapsulate datagram packet
outputBuffer.reset();
outputBuffer.write(NULL);
outputBuffer.write(NULL);
outputBuffer.write(NULL);
outputBuffer.write(remoteAddressType);
outputBuffer.write(remoteAddress);
outputBuffer.write(remotePort);
outputBuffer.write(p.getData());
byte[] data=outputBuffer.toByteArray();
p=new DatagramPacket(data,data.length,serverBoundAddress,serverBoundPort);
clientDatagramSocket.send(p);
}
/**
* An extended method for DatagramSocket
*
* Disconnects the socket. This does nothing if the socket is not
* connected.
*/
protected void disconnect()
{
if(stream)// Direct stream socket connection
throw new IllegalAccessError("Illegal called a specific method for DatagramSocket whne using Socket");
if(clientDatagramSocket!=null)
{
this.address=null;
this.port=-1;
clientDatagramSocket.disconnect();
}
else
initRemoteHost((InetAddress)null,-1);
}
/**
* Peek at the packet to see who it is from.
* @param return the address which the packet came from.
*/
protected int peek(InetAddress i) throws IOException
{
throw new IOException("Not implemented.");
}
/**
* Receive the datagram packet.
* @param Packet Received.
*/
protected void receive(DatagramPacket p) throws IOException
{
InetAddress packetAddress = p.getAddress();
if(address== null && packetAddress == null)
throw new IllegalArgumentException("Both of remote address and packet address are null.");
else if(packetAddress != null &&
!(packetAddress.equals(address) &&
p.getPort() == port))
{
connect(packetAddress,p.getPort());
}
else if(clientDatagramSocket==null)
connect(address,port);
if(proxyAddress==null)
{
clientDatagramSocket.receive(p);
return;
}
p.setAddress(serverBoundAddress);
p.setPort(serverBoundPort);
clientDatagramSocket.receive(p);
byte[] data=p.getData();
if(data.length<10
|| data[0]!=NULL || data[1]!=NULL || data[2]!=NULL
|| data[3]!=IP_V4)
throw new IOException("Unkown socks datagram packet: "+new String(data));
InetAddress sourceInetAddress=getInetAddress(data[3],data,4);
if(!sourceInetAddress.equals(address)
|| getPortValue(data,8)!=port)///Discard invalid datagram packet
{
receive(p);
return;
}
byte[] ba=new byte[data.length-10];
System.arraycopy(data,10,ba,0,ba.length);
p.setData(ba);
p.setAddress(address);
p.setPort(port);
}
/**
* Set the TTL (time-to-live) option.
* @param TTL to be set.
*
* @deprecated use setTimeToLive instead.
*/
protected void setTTL(byte ttl) throws IOException
{
throw new IOException("Not implemented deprecated function.");
}
/**
* Retrieve the TTL (time-to-live) option.
*
* @deprecated use getTimeToLive instead.
*/
protected byte getTTL() throws IOException
{
throw new IOException("Not implemented deprecated function.");
}
/**
* Set the TTL (time-to-live) option.
* @param TTL to be set.
*/
protected void setTimeToLive(int ttl) throws IOException
{
throw new IOException("Not implemented.");
}
/**
* Retrieve the TTL (time-to-live) option.
*/
protected int getTimeToLive() throws IOException
{
throw new IOException("Not implemented.");
}
/**
* Join the multicast group.
* @param multicast address to join.
*/
protected void join(InetAddress inetaddr) throws IOException
{
throw new IOException("Not implemented.");
}
/**
* Leave the multicast group.
* @param multicast address to leave.
*/
protected void leave(InetAddress inetaddr) throws IOException
{
throw new IOException("Not implemented.");
}
/**
* Get the datagram socket file descriptor
*/
protected FileDescriptor getFileDescriptor()
{
return null;//Not implemented.
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -