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/write client 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>=receivebuffer 2.如果应用读取数据很慢,那么receivebuffer要设置得大一点,避免阻塞sendbuffer。 3.应用程序如果要发送也要接受大量数据,则需要增加这两个值。 4.java中最好使用bufferoutputStream或者ByteBuffer,来写入足够数据的TCP块。 //立刻发送urgentdata的数据,而write的数据要flush之后才发送。server和client都要同时开启。 socket.setOOBInline(true); socket.sendUrgentData(65); public void setTrafficClass(int tc) * <UL> * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI> * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI> * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI> * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI> * </UL> 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 * <tt>(1, 0, 0)</tt>. 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 <tt>(0, 1, 2)</tt>. 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 channels static ReadableByteChannel newChannel(InputStream is); static WritableByteChannel newChannel(OutputStream os); // convert channels to streams static InputStream newInputStream(ReadableByteChannel ch); static OutputStream newOutputStream(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 status blocking TCP connect():connect() ilock noblocking 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 socket handShake 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, an trust manager tracing (the commas are optional): -Djavax.net.debug=SSL:handshake:data:trustmanager SSL system properties: https.cipherSuites https.protocals https.proxyHost https.proxyPort java.net.protocal.handler.pkgs javax.net.debug javax.net.ssl.keyStore javax.net.ssl.keyStorePassword javax.net.ssl.keyStoreType javax.net.trustStore javax.net.trustStorePassword javax.net.trustStoreType scalable secure socket: javax.net.ssl.Sslengine unicast UDP: ipv4 65507byte udp:512byte a ip package size udp:没有建立连接和关闭连接的开销;服务器和客户端管理简单; a:trasaction is request-reply;b:payloads is small;c:servers are stateless;d:Trasactions can be repeated; receive, send is synchronized reliable UDP:(DNS) 1.sequence number; 2 timeout and retransmits ACK and NACK based protocol scalable 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 address 3. IPV6 anycast only receive by any one of the group members TTL based Scopes Address based Scopes Tree-based protocals NACK-based protocals ACL Reactor,Proactor,leader-follower server