fundamental networking in java:1.summary用java开发网络编程应用优势在于:1.跨平台型2.轻量级线程模型 网络编程跟多线程结合3.安全性 没有指针,垃圾回收机制;很好的异常处理机制,oom异常也能捕获;未捕获的运行时异常只影响所在的线程,不影响进程。4.可扩展性灵活性,以及良好丰富的类库。java的网络库更简单易用。2 IP:Socket:一台机器的通讯节点称为socket,在java中,socket是java.net包里面的Socket,ServerSocket,DataGramSocket,MultiSocket的实例。IP地址java中用java.net.InetAddress来表示。java network address class包括:InetAddress:ip地址或者域名,指向远程地址。如果域名解析不了,则出错。 抽象类,有两个子类:Inet4Address和Inet6Address。这两个类智能通过InetAddress的静态方法获取,不能直接构造。包可见。InetSocketAddress extends SocketAddress:ip socket地址,用{ip,port}或者{hostname,port}表示。也能够单独用port构造,表示本机ip地址,所有本机网络地址。NetwordInterface:本机网络接口,由多个网络接口名称和对应的网络接口的ip地址列表构成。网络主机有两个特殊的网络地址:loopback:127.0.0.1 用来检测本机的host名称,或者检测本地ip地址是否可用wildcard:0.0.0.0 绑定了本机所有的ip地址IPV6支持IPV4,可以通过以下的环境变量对ipv4和ipv6进行设置java.net.preferlPv4Stack false(default)/true false:表示支持ipv4heipv6,true表示只支持ipv4,java.net.preferlPv6Address false(default)/true false,如果ipv6可用,则ipv4地址会覆盖掉ipv6地址,如果为true,则ipv6会覆盖ipv4地址,通讯地址使用ipv6.3.TCP: 可靠的,基于流的连接,双向的 两种TCP socket:active和passive(listening) serversocket:create a socket->binds to a port -> listen() -> loop accepte client connect -> read/writeclient socket:create a socket -> connect to a address -> read/write连接:三次握手:最多重试三次,第一次3-6s,后面double。关闭连接:四次握手server socket: 如果port设置为0,不设置,则系统会自动分配一个端口。如果设置为1-1023端口,需要高级用户权限。 backlog:请求队列最大长度,服务器端等待请求的最大队列数。默认50. localaddress:server监听的本机地址,默认是所有的。 setReuseAddress(boolean on):如果停止服务之后,需要马上重启服务,那么之前的端口可能还占用导致启动不了。设置该参数表示该地址可以重用。 setReceiveBufferSize (int size):设置接收缓冲区大小。必须在绑定端口之前设置。为了达到更大的吞吐量,可以设置得大一点(>64k)。但是跟sendBufferSize最好配合使用。client socket: 如果port不设置,则默认跟连接的server一致。 setSendBufferSize(int size)必须在connect之前设置 Socket IO:DataOutputStream DataInputStream ObjectInputStream ObjectOutputStream可能导致死锁:下面两行代码顺序可能导致死锁,因为server和client的ObjectInputStream都尝试读取对方的object stream header的数据,这样导致server和client都在等待,处于死锁。获取ObjectOutputStream必须在获取ObjectInputStream之前。ObjectInputStream in = new ObjectInputStream(socket.getInputStream());ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());InputStream.available()获取当前socket buffer的大小。channel IO:output shutdown:半关闭 class Socket{void shutdownOutput() throws IOException;boolean isOutputShutdown();}特点:1.可读不可写;2.当socket关闭时,会close该连接。3.另一端read时会得到EOF异常在proxy中,copy input to output时需要close output,这样才能把代理端的EOF也复制。如果不需要read操作,可以关闭output,减少reply数据的计算和传输的资源。Socket.close()异步操作input shutdown:半关闭class Socket{void shutdownInput() throws IOException;boolean isInputShutdown();}特点:1直接丢弃数据,远程端无法感知本地已经关闭input。close a connected socket:class Socket{void close() throws IOException;boolean isClosed();}1.socket.close() 2 socket.getOutputStream().close(); 3 socket.getInputStream().close(); close a server socket:class ServerSocket{void close() throws IOException;boolean isClosed();}socket factory:java 提供三种socket factory: java.net socket factory:SocketImplFactory Socket类的public static synchronized void setSocketImplFactory(SocketImplFactory fac)只能在一个jvm中调用一次,需要RuntimePermission ‘setFactory’ RMI socket factory:RMISocketFactory RMIServerSocketFactory RMIClientSocketFactory ssl socket factory.socket:sendbuffer和receivebuffer的大小由tcp协议栈决定,不是由jvm。传统的tcp实现默认是2kb,但是现在更多的如28kb,32kb,64kb。1.以太网最好从4kb增大到16kb >=3 * MSS sendbuffer>=receivebuffer2.如果应用读取数据很慢,那么receivebuffer要设置得大一点,避免阻塞sendbuffer。3.应用程序如果要发送也要接受大量数据,则需要增加这两个值。4.java中最好使用bufferoutputStream或者ByteBuffer,来写入足够数据的TCP块。//立刻发送urgentdata的数据,而write的数据要flush之后才发送。server和client都要同时开启。 socket.setOOBInline(true); socket.sendUrgentData(65); public void setTrafficClass(int tc) *
* IPTOS_LOWCOST (0x02)
* IPTOS_RELIABILITY (0x04)
* IPTOS_THROUGHPUT (0x08)
* IPTOS_LOWDELAY (0x10)
*
If the * application prefers short connection time over both low latency and high * bandwidth, for example, then it could invoke this method with the values *
(1, 0, 0). If the application prefers high bandwidth above low * latency, and low latency above short connection time, then it could * invoke this method with the values
(0, 1, 2). public void setPerformancePreferences(int connectionTime, int latency, int bandwidth)scaable IO:channel create:FileChannel FileInputStream.getChannel();FileChannel FileOutputStream.getChannel();FileChannel RandomAccessFile.getChannel();SocketChannel channel = SocketChannel.open();Socket socket = channel.socket();ServerSocketChannel channel = ServerSocketChannel.open();ServerSocket serverSocket = channel.socket();DatagramChannel channel = DatagramChannel.open();DatagramSocket datagramSocket = channel.socket();//Pipe pipe = Pipe.open();Pipe.SinkChannel sinkChannel = pipe.sink();Pipe.SourceChannel sourceChannel = pipe.source();Stream和channel的转换:Channels.java//not buffered,not support mart/reset operation;thread safe;only be use in blocking mode;closing them cause the underlying channel to be closed;class Channels {// convert streams to channelsstatic ReadableByteChannel newChannel(InputStream is);static WritableByteChannel newChannel(OutputStream os);// convert channels to streamsstatic InputStreamnewInputStream(ReadableByteChannel ch);static OutputStreamnewOutputStream(WritableByteChannel ch);}selector的select方法:如果返回0,则可能超时selector被异步唤醒;a register key被异步取消。 selectkey set只有在调用select(),select(long timeout)才被更新,处理完之后需要显示remove掉已经处理过得selectkey。selector.wakeup() will cause的next first block return immediately。wakeup():set a boolean statusblocking TCP connect():connect() ilocknoblocking TCP connect():cnnect() return true immediately,finishConnect() to check connect is ok.isConnectionPending() and finishConnect() only user in noblocking mode.socketChannel.close();1.cannel the selectkey associated with the channel;2 channel.close();must invoke selector.selectNow();1.only use OP_CONNECT on unconnect socket;it must be removed from keys as soon as channel is ready;2.only use OP_WRITE on connect socket;firewalls:1.transport firewalls;2application firewalls.HTTP proxy server:java 能够通过设置环境变量http.proxyHost和http.proxyPort通过代理服务器发送http请求。to get http tunnelling in rmi or httpConnect.Socket proxy:socksProxyHost and socksProxyPort to user a socket proxy java.net.Proxy:secure sockethandShake protocal:SSlSocket:1.firest create take more time;2use bufferOutputStream;3 not support OOBinline;4.SSlSocket.getInputStream().available() always return 0. 5.serveer/client must close at the same time,not support shutdownInput or shutDownoutput(a) To view all debugging messages:-Djavax.net.debug=all(b) To view the hexadecimal dumps of each handshake message: -Djavax.net.debug=ssl:handshake:data(c) To view the hexadecimal dumps of each handshake message, antrust manager tracing (the commas are optional):-Djavax.net.debug=SSL:handshake:data:trustmanagerSSL system properties:https.cipherSuiteshttps.protocalshttps.proxyHosthttps.proxyPortjava.net.protocal.handler.pkgsjavax.net.debugjavax.net.ssl.keyStorejavax.net.ssl.keyStorePasswordjavax.net.ssl.keyStoreTypejavax.net.trustStorejavax.net.trustStorePasswordjavax.net.trustStoreTypescalable secure socket:javax.net.ssl.Sslengineunicast UDP:ipv4 65507byteudp:512byte a ip package sizeudp:没有建立连接和关闭连接的开销;服务器和客户端管理简单;a:trasaction is request-reply;b:payloads is small;c:servers are stateless;d:Trasactions can be repeated;receive, send is synchronizedreliable UDP:(DNS) 1.sequence number; 2 timeout and retransmitsACK and NACK based protocolscalable UDP:muliticast UDP:1. multicast address a dynamic group address resuce the load;receive the package almost at the same time;fesable; reliable;co-operation from routers;security;2. broadcast a static group address3. IPV6 anycast only receive by any one of the group membersTTL based ScopesAddress based ScopesTree-based protocalsNACK-based protocalsACLReactor,Proactor,leader-follower server