- 浏览: 981266 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
java Socket用法详解:http://blog.csdn.net/semillon/article/details/7515926
JAVA 通过 Socket 实现 TCP 编程 :http://blog.csdn.net/qq_23473123/article/details/51461894
Socket和ServerSocket学习笔记:http://www.cnblogs.com/rond/p/3565113.html
Socket缓冲区探讨,是否有拆包的方式:http://www.cnblogs.com/cfas/p/5795350.html
Socket TCP粘包拆包 :http://blog.csdn.net/robinjwong/article/details/50155115
Socket 粘包 封包 拆包 :http://blog.csdn.net/bristar_zon/article/details/38239285
对UDP socket缓冲区的理解:http://blog.csdn.net/vonzhoufz/article/details/39080259
通过mark和reset方法重复利用InputStream:http://zhangbo-peipei-163-com.iteye.com/blog/2022460
在以前的工作中接触过MINA,没有深入研究过,从今天起,我们从Socket(阻塞式),JavaNIO(非阻塞式),JUC,再到MINA,深入解析一下java网络编程,今天我们先来看一下java Socket编程,我们要做的是一个可以计算加法与乘法的Server,客户端发送计算数值,服务器(多线程)接受客户端发送过来的数值,并将计算结果发送给客户端,首先我们要定义客户端与
服务器通信协议格式:如下图
具体实现:
协议常量:
协议辅助工具:
服务端:
Socket处理线程:
客户端:
服务端控制台输出:
主机名:donaldHP
主机地址:192.168.132.126
服务器启动成功.........
服务器接受客户端连接.........
开始处理Socket........
//第一次解析
从接受缓冲区读取的实际协议长度为:28
开始解析计算协议......
计算协议解析完毕......
开始发送计算结果协议......
//15+6
服务器计算结果为:21
发送计算结果协议结束......
//第二次解析
从接受缓冲区读取的实际协议长度为:28
开始解析计算协议......
计算协议解析完毕......
开始发送计算结果协议......
//17*8
服务器计算结果为:136
发送计算结果协议结束......
客户端控制台输出:
连接服务器成功...........
发送加法计算协议开始...........
发送加法计算协议结束...........
发送乘法计算协议开始...........
发送乘法计算协议结束...........
等待服务器计算结果...........
//第一次解析结果
从接受缓冲区读取协议编码的实际长度为:6
协议编码:300200
结果值长度为:2
// 4为结果值长度2+协议结束符2
从接受缓冲区读取计算结果值和结束符实际长度为:4
计算结果协议结束:4
//15+6
计算结果为:21
//第二次解析结果
从接受缓冲区读取协议编码的实际长度为:6
协议编码:300200
结果值长度为:3
// 5为结果值长度3+协议结束符2
从接受缓冲区读取计算结果值和结束符实际长度为:5
计算结果协议结束:5
//17*8
计算结果为:136
总结:
java socket编程是阻塞模式的,从socket获取InputStream,OutputStream,而InputStream,OutputStream要经过
(BufferedInputStream,BufferedOutputStream),(DataInputStream,DataOutputStream)等的包装才可以写读socket的缓冲区;输入流skip函数,可以丢掉一些不必要的包,mark,reset函数可以标记读取位置,从标记位置从新读取;flush函数发送缓冲区里的所有数据,我们这里是强制清空缓冲区,实际不要这样做,以免影响数据传输效率。
辅助测试类:
//FilterInputStream
//FilterOutputStream
JAVA 通过 Socket 实现 TCP 编程 :http://blog.csdn.net/qq_23473123/article/details/51461894
Socket和ServerSocket学习笔记:http://www.cnblogs.com/rond/p/3565113.html
Socket缓冲区探讨,是否有拆包的方式:http://www.cnblogs.com/cfas/p/5795350.html
Socket TCP粘包拆包 :http://blog.csdn.net/robinjwong/article/details/50155115
Socket 粘包 封包 拆包 :http://blog.csdn.net/bristar_zon/article/details/38239285
对UDP socket缓冲区的理解:http://blog.csdn.net/vonzhoufz/article/details/39080259
通过mark和reset方法重复利用InputStream:http://zhangbo-peipei-163-com.iteye.com/blog/2022460
在以前的工作中接触过MINA,没有深入研究过,从今天起,我们从Socket(阻塞式),JavaNIO(非阻塞式),JUC,再到MINA,深入解析一下java网络编程,今天我们先来看一下java Socket编程,我们要做的是一个可以计算加法与乘法的Server,客户端发送计算数值,服务器(多线程)接受客户端发送过来的数值,并将计算结果发送给客户端,首先我们要定义客户端与
服务器通信协议格式:如下图
具体实现:
协议常量:
package socket; /** * 协议常量 * @author donald * 2017年2月11日 * 下午12:05:29 */ public class ProtocolConstants { /** * 加法协议编码 */ public static final String SUM_PROTOCOL_300000 = "300000"; /** * 乘法协议编码 */ public static final String MULTI_PROTOCOL_300100 = "300100"; /** * 计算结果 */ public static final String ACK_PROTOCOL_300200 = "300200"; /** * 协议编码长度 */ public static final Integer PROTOCOL_CODE_LENGTH = 6; /** * 协议操作数长度 */ public static final Integer OPERATE_NUM_LENGTH = 10; /** * 协议计算结果长度 */ public static final Integer PROTOCOL_ACK_LENGTH = 2; /** * 协议结束符 */ public static final String PROTOCOL_END = "\r\n"; /** * 协议结束符长度 */ public static final Integer PROTOCOL_END_LENGTH = 2; /** * 字符集 */ public static final String CHARSET_UTF8 = "UTF-8"; }
协议辅助工具:
package socket; /** * 协议辅助工具 * @author donald * 2017年2月11日 * 下午12:05:13 */ public class ProtocolUtils { private static volatile ProtocolUtils instance = null; public static synchronized ProtocolUtils getInstance(){ if(instance == null){ instance = new ProtocolUtils(); } return instance; } /** * 如果orgStr的长度不够length,左侧填充0 * @param orgStr * @param length * @return */ public String fillString(String orgStr, int length){ if(orgStr.length() < length){ int orgStrLength = orgStr.length(); int zeroNum = length - orgStrLength; for(int i=0; i< zeroNum; i++){ orgStr = "0" + orgStr; } } return orgStr; } public static void main(String[] args) { int firstNum = 15; String firstNumStr = String.valueOf(firstNum); if(firstNumStr.length() <= 10){ firstNumStr = ProtocolUtils.getInstance().fillString(firstNumStr,10); } System.out.println("=======firstNumStr:"+firstNumStr); System.out.println("=======firstNumStr Integer Value:"+Integer.valueOf(firstNumStr)); } }
服务端:
package socket; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; /** * Socket Server * @author donald * 2017年2月12日 * 下午2:43:58 */ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TcpServerSocket { private static int port = 4003;//端口号 private static int backlog = 20;//Server最大连接数 private static InetAddress serverHost = null;//server地址 static{ try { serverHost = InetAddress.getLocalHost(); System.out.println("主机名:"+serverHost.getHostName()); System.out.println("主机地址:"+serverHost.getHostAddress()); } catch (UnknownHostException e) { System.out.println("获取主机地址信息异常:"+e.getMessage()); e.printStackTrace(); } } //搭建服务器端 public static void main(String[] args){ TcpServerSocket tcpServerSocket = new TcpServerSocket(); //创建一个服务器端Socket,即SocketService tcpServerSocket.startServer(); } public void startServer(){ ServerSocket tcpServer=null; ExecutorService exec = Executors.newCachedThreadPool(); try { tcpServer=new ServerSocket(port,backlog,serverHost); System.out.println("服务器启动成功........."); while(true){ try { Socket socket = tcpServer.accept(); System.out.println("服务器接受客户端连接........."); SocketHandleRunnable sHandleRunnable = new SocketHandleRunnable(socket); exec.execute(sHandleRunnable); //有返回值 //exec.submit(sHandleRunnable); } catch (IOException e) { e.printStackTrace(); } } } catch (IOException e) { System.out.println("服务器启动失败:"+e.getMessage()); e.printStackTrace(); } finally{ try { tcpServer.close(); } catch (IOException e) { e.printStackTrace(); } exec.shutdown(); } } }
Socket处理线程:
package socket; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /** * Socket处理线程 * @author donald * 2017年2月12日 * 下午2:54:47 */ public class SocketHandleRunnable implements Runnable { private static ProtocolUtils protocolUtils = null; private Socket socket; static { protocolUtils = ProtocolUtils.getInstance(); } public SocketHandleRunnable(Socket socket) { super(); this.socket = socket; } @Override public void run() { System.out.println("开始处理Socket........"); InputStream serverInputStream = null; OutputStream serverOutputStream = null; BufferedInputStream serverBufferInputStream = null; BufferedOutputStream serverBufferOutputStream = null; try { serverInputStream = socket.getInputStream(); serverOutputStream = socket.getOutputStream(); serverBufferInputStream = new BufferedInputStream(serverInputStream); serverBufferOutputStream = new BufferedOutputStream(serverOutputStream); int protocolLenght = ProtocolConstants.PROTOCOL_CODE_LENGTH + ProtocolConstants.OPERATE_NUM_LENGTH*2 + ProtocolConstants.PROTOCOL_END_LENGTH; boolean flag = true; while(flag){ if(serverBufferInputStream.available() >= protocolLenght){ byte[] protcBuf = new byte[protocolLenght]; int readLength = serverBufferInputStream.read(protcBuf, 0, protocolLenght); System.out.println("从接受缓冲区读取的实际协议长度为:"+readLength); if(readLength == protocolLenght){ String protcStr = new String(protcBuf,ProtocolConstants.CHARSET_UTF8); String endStr = protcStr.substring(protcStr.length()-2, protcStr.length()); if(endStr.equals(ProtocolConstants.PROTOCOL_END)){ System.out.println("开始解析计算协议......"); String protocolCode = protcStr.substring(0, 6); String firstNumStr = protcStr.substring(6, 16); int firstNum = Integer.valueOf(firstNumStr); String secNumStr = protcStr.substring(16, 26); int secNum = Integer.valueOf(secNumStr); System.out.println("计算协议解析完毕......"); int result = 0; if(protocolCode.equals(ProtocolConstants.SUM_PROTOCOL_300000)){ result = firstNum + secNum; } if(protocolCode.equals(ProtocolConstants.MULTI_PROTOCOL_300100)){ result = firstNum*secNum; } System.out.println("开始发送计算结果协议......"); //将计算结果值发送给Client //发送计算结果协议编码 byte[] AckProtocolBytes = ProtocolConstants.ACK_PROTOCOL_300200.getBytes(ProtocolConstants.CHARSET_UTF8); serverBufferOutputStream.write(AckProtocolBytes); //结果值 String resultStr = String.valueOf(result); System.out.println("服务器计算结果为:"+resultStr); byte[] resultBytes = resultStr.getBytes(ProtocolConstants.CHARSET_UTF8); //结果长度 int resultLength = resultStr.length(); String reultLenthStr = String.valueOf(resultLength); reultLenthStr = protocolUtils.fillString(reultLenthStr, ProtocolConstants.PROTOCOL_ACK_LENGTH); byte[] resultLengthBytes = reultLenthStr.getBytes(ProtocolConstants.CHARSET_UTF8); serverBufferOutputStream.write(resultLengthBytes); //发送结果值 serverBufferOutputStream.write(resultBytes); //发送结束符 serverBufferOutputStream.write(ProtocolConstants.PROTOCOL_END.getBytes(ProtocolConstants.CHARSET_UTF8)); System.out.println("发送计算结果协议结束......"); //将缓冲区发送到Client,我们这里是强制清空缓冲区,实际不要这样做,以免影响数据传输效率 serverBufferOutputStream.flush(); } } if(readLength < 0){ System.out.println("与客户端失去连接....."); } if(readLength < protocolLenght){ //从缓冲区继续读取数据,直至读取的数据长度为协议长度+结束符; //当数据解析异常时,可以用InputStream.skip(long n),丢弃一些数据,以保证一次协议包的完成性 } } } } catch (IOException e) { e.printStackTrace(); } finally{ try { serverBufferInputStream.close(); serverBufferOutputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("Socket处理结束........"); } }
客户端:
package socket; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * Socket Client * @author donald * 2017年2月12日 * 下午2:43:46 */ public class TcpClient { private static ProtocolUtils protocolUtils = null; private static final String ip ="192.168.132.126"; private static final int port = 4003; private static final int bufferSize = 1024; static { protocolUtils = ProtocolUtils.getInstance(); } // 搭建客户端 public static void main(String[] args){ Socket socket = null; OutputStream clientOutputStream = null; InputStream clientInputStream = null; BufferedInputStream clientBufferInputStream = null; BufferedOutputStream clientBufferOutputStream = null; try { socket = new Socket(ip, port); socket.setSendBufferSize(bufferSize); socket.setReceiveBufferSize(bufferSize); socket.setKeepAlive(true); if(socket.isConnected()){ System.out.println("连接服务器成功..........."); try { clientOutputStream = socket.getOutputStream(); clientInputStream = socket.getInputStream(); clientBufferInputStream = new BufferedInputStream(clientInputStream); clientBufferOutputStream = new BufferedOutputStream(clientOutputStream); //只做长度为10以内的加法与乘法 //加法 System.out.println("发送加法计算协议开始..........."); //发送协议编码 byte[] sumProtocolBytes = ProtocolConstants.SUM_PROTOCOL_300000.getBytes(ProtocolConstants.CHARSET_UTF8); clientBufferOutputStream.write(sumProtocolBytes); //发送第一个操作数 int firstNum = 15; String firstNumStr = String.valueOf(firstNum); //如果操作符不够长度,则左侧补零 firstNumStr = protocolUtils.fillString(firstNumStr, ProtocolConstants.OPERATE_NUM_LENGTH); byte[] firstNumBytes = firstNumStr.getBytes(ProtocolConstants.CHARSET_UTF8); clientBufferOutputStream.write(firstNumBytes); //发送第二个操作数 int secondNum = 6; String secondNumStr = String.valueOf(secondNum); secondNumStr = protocolUtils.fillString(secondNumStr, ProtocolConstants.OPERATE_NUM_LENGTH); byte[] secondNumBytes = secondNumStr.getBytes(ProtocolConstants.CHARSET_UTF8); clientBufferOutputStream.write(secondNumBytes); //发送协议结束符 byte[] endBytes = ProtocolConstants.PROTOCOL_END.getBytes(ProtocolConstants.CHARSET_UTF8); clientBufferOutputStream.write(endBytes); System.out.println("发送加法计算协议结束..........."); System.out.println("发送乘法计算协议开始..........."); // 乘法 byte[] sumProtocolBytesx = ProtocolConstants.MULTI_PROTOCOL_300100.getBytes(ProtocolConstants.CHARSET_UTF8); clientBufferOutputStream.write(sumProtocolBytesx); //发送第一个操作数 int firstNumx = 17; String firstNumStrx = String.valueOf(firstNumx); //如果操作符不够长度,则左侧补零 firstNumStrx = protocolUtils.fillString(firstNumStrx, ProtocolConstants.OPERATE_NUM_LENGTH); byte[] firstNumBytesx = firstNumStrx.getBytes(ProtocolConstants.CHARSET_UTF8); clientBufferOutputStream.write(firstNumBytesx); //发送第二个操作数 int secondNumx = 8; String secondNumStrx = String.valueOf(secondNumx); secondNumStrx = protocolUtils.fillString(secondNumStrx, ProtocolConstants.OPERATE_NUM_LENGTH); byte[] secondNumBytesx = secondNumStrx.getBytes(ProtocolConstants.CHARSET_UTF8); clientBufferOutputStream.write(secondNumBytesx); //发送协议结束符 clientBufferOutputStream.write(endBytes); //将缓冲区发送到Server,我们这里是强制清空缓冲区,实际不要这样做,以免影响数据传输效率 clientBufferOutputStream.flush(); System.out.println("发送乘法计算协议结束..........."); try { Thread.sleep(3000); System.out.println("等待服务器计算结果..........."); } catch (InterruptedException e) { e.printStackTrace(); } boolean flag = true; //返回的协议长度,协议编码6+结果长度2 int ackLength = ProtocolConstants.PROTOCOL_CODE_LENGTH + ProtocolConstants.PROTOCOL_ACK_LENGTH; while(flag){ // System.out.println("等待解析服务器计算结果..........."); //结果值长度 int valueLenth = 0; //接受缓冲区的可利用长度大于等于8 if(clientBufferInputStream.available()>=ackLength){ byte[] codeBuf = new byte[6]; int codeLength = clientBufferInputStream.read(codeBuf, 0, 6); System.out.println("从接受缓冲区读取协议编码的实际长度为:"+codeLength); if(codeLength == 6){ String ackProtcolCode = new String(codeBuf,ProtocolConstants.CHARSET_UTF8); if(ackProtcolCode.equals(ProtocolConstants.ACK_PROTOCOL_300200)){ System.out.println("协议编码:"+ackProtcolCode); byte[] resultBuf = new byte[2]; int resultLength = clientBufferInputStream.read(resultBuf, 0, 2); if(resultLength == 2){ String resultLengthStr = new String(resultBuf,ProtocolConstants.CHARSET_UTF8); valueLenth = Integer.valueOf(resultLengthStr); System.out.println("结果值长度为:"+valueLenth); } if(resultLength < 0){ //与服务器失去连接 flag = false; System.out.println("与服务器失去连接....."); } } } if(codeLength < 0){ //与服务器失去连接 flag = false; System.out.println("与服务器失去连接....."); } } if(valueLenth > 0){ //结果值+协议结束符(2) int valueEndLenth = valueLenth + ProtocolConstants.PROTOCOL_END_LENGTH; if(clientBufferInputStream.available()>=valueEndLenth){ byte[] valueEndBuf = new byte[valueEndLenth]; int readLength = clientBufferInputStream.read(valueEndBuf, 0, valueEndLenth); System.out.println("从接受缓冲区读取计算结果值和结束符实际长度为:"+readLength); if(readLength == valueEndLenth){ String valueEndStr = new String(valueEndBuf,ProtocolConstants.CHARSET_UTF8); String endStr = valueEndStr.substring(valueEndStr.length()-2, valueEndStr.length()); if(endStr.equals(ProtocolConstants.PROTOCOL_END)){ System.out.println("计算结果协议结束:"+readLength); String valueStr = valueEndStr.substring(0,valueEndStr.length()-2); System.out.println("计算结果为:"+valueStr); } } if(readLength < 0){ //与服务器失去连接 flag = false; System.out.println("与服务器失去连接....."); } } } } } catch (IOException e) { System.out.println("服务器IO异常:"+e.getMessage()); e.printStackTrace(); } finally{ try { clientBufferInputStream.close(); clientInputStream.close(); } catch (IOException e) { System.out.println("关闭资源异常:"+e.getMessage()); e.printStackTrace(); } } } } catch (UnknownHostException e) { System.out.println("连接服务器异常:"+e.getMessage()); e.printStackTrace(); } catch (IOException e) { System.out.println("连接服务器IO异常:"+e.getMessage()); e.printStackTrace(); } finally{ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
服务端控制台输出:
主机名:donaldHP
主机地址:192.168.132.126
服务器启动成功.........
服务器接受客户端连接.........
开始处理Socket........
//第一次解析
从接受缓冲区读取的实际协议长度为:28
开始解析计算协议......
计算协议解析完毕......
开始发送计算结果协议......
//15+6
服务器计算结果为:21
发送计算结果协议结束......
//第二次解析
从接受缓冲区读取的实际协议长度为:28
开始解析计算协议......
计算协议解析完毕......
开始发送计算结果协议......
//17*8
服务器计算结果为:136
发送计算结果协议结束......
客户端控制台输出:
连接服务器成功...........
发送加法计算协议开始...........
发送加法计算协议结束...........
发送乘法计算协议开始...........
发送乘法计算协议结束...........
等待服务器计算结果...........
//第一次解析结果
从接受缓冲区读取协议编码的实际长度为:6
协议编码:300200
结果值长度为:2
// 4为结果值长度2+协议结束符2
从接受缓冲区读取计算结果值和结束符实际长度为:4
计算结果协议结束:4
//15+6
计算结果为:21
//第二次解析结果
从接受缓冲区读取协议编码的实际长度为:6
协议编码:300200
结果值长度为:3
// 5为结果值长度3+协议结束符2
从接受缓冲区读取计算结果值和结束符实际长度为:5
计算结果协议结束:5
//17*8
计算结果为:136
总结:
java socket编程是阻塞模式的,从socket获取InputStream,OutputStream,而InputStream,OutputStream要经过
(BufferedInputStream,BufferedOutputStream),(DataInputStream,DataOutputStream)等的包装才可以写读socket的缓冲区;输入流skip函数,可以丢掉一些不必要的包,mark,reset函数可以标记读取位置,从标记位置从新读取;flush函数发送缓冲区里的所有数据,我们这里是强制清空缓冲区,实际不要这样做,以免影响数据传输效率。
辅助测试类:
package socket; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.UnknownHostException; /** * 辅助测试 * @author donald * 2017年2月12日 * 下午5:12:28 */ public class testByte { public static void main(String[] args) { try { String end = "\r\n"; byte[] endBytes = end.getBytes("UTF-8"); System.out.println("====endBytes Length:"+endBytes.length); String endStr = new String(endBytes,"UTF-8"); System.out.println("是否结束:"+endStr.equals("\r\n")); System.out.println("====结束符:"+endStr); String sumProtocol = "300000"; byte[] sumProtocolBytes = sumProtocol.getBytes("UTF-8"); System.out.println("====sumProtocol Length:"+sumProtocolBytes.length); String sumProtocolStr = new String(sumProtocolBytes,"UTF-8"); System.out.println("====加法协议:"+sumProtocolStr); String multiProtocol = "3000100"; byte[] multiProtocolBytes = multiProtocol.getBytes("UTF-8"); System.out.println("====multiProtocol Length:"+multiProtocolBytes.length); String multiProtocolStr = new String(multiProtocolBytes,"UTF-8"); System.out.println("====乘法协议:"+multiProtocolStr); int firstNum = 15; String firstNumStr = String.valueOf(firstNum); //如果第一个操作符不够长度,则补零 if(firstNumStr.length()<10){ int NumLength = firstNumStr.length(); int zeroNum = 10 - NumLength; String zeroNumStr=""; for(int i=0; i< zeroNum; i++){ zeroNumStr += "0"; } firstNumStr = zeroNumStr + firstNumStr; } System.out.println("补零后的字符串:"+firstNumStr); try { InetAddress host = InetAddress.getLocalHost(); System.out.println("主机名:"+host.getHostName()); System.out.println("主机地质:"+host.getHostAddress()); } catch (UnknownHostException e) { e.printStackTrace(); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }
//ServerSocket //服务端 package java.net; import java.io.FileDescriptor; import java.io.IOException; import java.nio.channels.ServerSocketChannel; import java.security.AccessController; import java.security.PrivilegedExceptionAction; /** * This class implements server sockets. A server socket waits for * requests to come in over the network. It performs some operation * based on that request, and then possibly returns a result to the requester. * <p> * The actual work of the server socket is performed by an instance * of the <code>SocketImpl</code> class. An application can * change the socket factory that creates the socket * implementation to configure itself to create sockets * appropriate to the local firewall. * * @author unascribed * @see java.net.SocketImpl * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @see java.nio.channels.ServerSocketChannel * @since JDK1.0 */ public class ServerSocket implements java.io.Closeable {
//Socket //客户端 /** * This class implements client sockets (also called just * "sockets"). A socket is an endpoint for communication * between two machines. * <p> * The actual work of the socket is performed by an instance of the * <code>SocketImpl</code> class. An application, by changing * the socket factory that creates the socket implementation, * can configure itself to create sockets appropriate to the local * firewall. * * @author unascribed * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory) * @see java.net.SocketImpl * @see java.nio.channels.SocketChannel * @since JDK1.0 */ public class Socket implements java.io.Closeable {
//InputStream //从Socket获取的InputStream,要经过BufferedInputStream,DataInputStream //等的包装才可以读数据,注意skip,mark,reset函数 package java.io; /** * This abstract class is the superclass of all classes representing * an input stream of bytes. * * <p> Applications that need to define a subclass of <code>InputStream</code> * must always provide a method that returns the next byte of input. * * @author Arthur van Hoff * @see java.io.BufferedInputStream * @see java.io.ByteArrayInputStream * @see java.io.DataInputStream * @see java.io.FilterInputStream * @see java.io.InputStream#read() * @see java.io.OutputStream * @see java.io.PushbackInputStream * @since JDK1.0 */ public abstract class InputStream implements Closeable { // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to // use when skipping. private static final int MAX_SKIP_BUFFER_SIZE = 2048; /** * Reads the next byte of data from the input stream. The value byte is * returned as an <code>int</code> in the range <code>0</code> to * <code>255</code>. If no byte is available because the end of the stream * has been reached, the value <code>-1</code> is returned. This method * blocks until input data is available, the end of the stream is detected, * or an exception is thrown. * * <p> A subclass must provide an implementation of this method. * * @return the next byte of data, or <code>-1</code> if the end of the * stream is reached. * @exception IOException if an I/O error occurs. */ public abstract int read() throws IOException; /** * Reads some number of bytes from the input stream and stores them into * the buffer array <code>b</code>. The number of bytes actually read is * returned as an integer. This method blocks until input data is * available, end of file is detected, or an exception is thrown. * * <p> If the length of <code>b</code> is zero, then no bytes are read and * <code>0</code> is returned; otherwise, there is an attempt to read at * least one byte. If no byte is available because the stream is at the * end of the file, the value <code>-1</code> is returned; otherwise, at * least one byte is read and stored into <code>b</code>. * * <p> The first byte read is stored into element <code>b[0]</code>, the * next one into <code>b[1]</code>, and so on. The number of bytes read is, * at most, equal to the length of <code>b</code>. Let <i>k</i> be the * number of bytes actually read; these bytes will be stored in elements * <code>b[0]</code> through <code>b[</code><i>k</i><code>-1]</code>, * leaving elements <code>b[</code><i>k</i><code>]</code> through * <code>b[b.length-1]</code> unaffected. * * <p> The <code>read(b)</code> method for class <code>InputStream</code> * has the same effect as: <pre><code> read(b, 0, b.length) </code></pre> * * @param b the buffer into which the data is read. * @return the total number of bytes read into the buffer, or * <code>-1</code> if there is no more data because the end of * the stream has been reached. * @exception IOException If the first byte cannot be read for any reason * other than the end of the file, if the input stream has been closed, or * if some other I/O error occurs. * @exception NullPointerException if <code>b</code> is <code>null</code>. * @see java.io.InputStream#read(byte[], int, int) */ public int read(byte b[]) throws IOException { return read(b, 0, b.length); } /** * Reads up to <code>len</code> bytes of data from the input stream into * an array of bytes. An attempt is made to read as many as * <code>len</code> bytes, but a smaller number may be read. * The number of bytes actually read is returned as an integer. * * <p> This method blocks until input data is available, end of file is * detected, or an exception is thrown. * * <p> If <code>len</code> is zero, then no bytes are read and * <code>0</code> is returned; otherwise, there is an attempt to read at * least one byte. If no byte is available because the stream is at end of * file, the value <code>-1</code> is returned; otherwise, at least one * byte is read and stored into <code>b</code>. * * <p> The first byte read is stored into element <code>b[off]</code>, the * next one into <code>b[off+1]</code>, and so on. The number of bytes read * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of * bytes actually read; these bytes will be stored in elements * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>, * leaving elements <code>b[off+</code><i>k</i><code>]</code> through * <code>b[off+len-1]</code> unaffected. * * <p> In every case, elements <code>b[0]</code> through * <code>b[off]</code> and elements <code>b[off+len]</code> through * <code>b[b.length-1]</code> are unaffected. * * <p> The <code>read(b,</code> <code>off,</code> <code>len)</code> method * for class <code>InputStream</code> simply calls the method * <code>read()</code> repeatedly. If the first such call results in an * <code>IOException</code>, that exception is returned from the call to * the <code>read(b,</code> <code>off,</code> <code>len)</code> method. If * any subsequent call to <code>read()</code> results in a * <code>IOException</code>, the exception is caught and treated as if it * were end of file; the bytes read up to that point are stored into * <code>b</code> and the number of bytes read before the exception * occurred is returned. The default implementation of this method blocks * until the requested amount of input data <code>len</code> has been read, * end of file is detected, or an exception is thrown. Subclasses are encouraged * to provide a more efficient implementation of this method. * * @param b the buffer into which the data is read. * @param off the start offset in array <code>b</code> * at which the data is written. * @param len the maximum number of bytes to read. * @return the total number of bytes read into the buffer, or * <code>-1</code> if there is no more data because the end of * the stream has been reached. * @exception IOException If the first byte cannot be read for any reason * other than end of file, or if the input stream has been closed, or if * some other I/O error occurs. * @exception NullPointerException If <code>b</code> is <code>null</code>. * @exception IndexOutOfBoundsException If <code>off</code> is negative, * <code>len</code> is negative, or <code>len</code> is greater than * <code>b.length - off</code> * @see java.io.InputStream#read() */ public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i; } /** * Skips over and discards <code>n</code> bytes of data from this input * stream. The <code>skip</code> method may, for a variety of reasons, end * up skipping over some smaller number of bytes, possibly <code>0</code>. * This may result from any of a number of conditions; reaching end of file * before <code>n</code> bytes have been skipped is only one possibility. * The actual number of bytes skipped is returned. If <code>n</code> is * negative, no bytes are skipped. * * <p> The <code>skip</code> method of this class creates a * byte array and then repeatedly reads into it until <code>n</code> bytes * have been read or the end of the stream has been reached. Subclasses are * encouraged to provide a more efficient implementation of this method. * For instance, the implementation may depend on the ability to seek. * * @param n the number of bytes to be skipped. * @return the actual number of bytes skipped. * @exception IOException if the stream does not support seek, * or if some other I/O error occurs. */ public long skip(long n) throws IOException { long remaining = n; int nr; if (n <= 0) { return 0; } int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining); byte[] skipBuffer = new byte[size]; while (remaining > 0) { nr = read(skipBuffer, 0, (int)Math.min(size, remaining)); if (nr < 0) { break; } remaining -= nr; } return n - remaining; } /** * Returns an estimate of the number of bytes that can be read (or * skipped over) from this input stream without blocking by the next * invocation of a method for this input stream. The next invocation * might be the same thread or another thread. A single read or skip of this * many bytes will not block, but may read or skip fewer bytes. * * <p> Note that while some implementations of {@code InputStream} will return * the total number of bytes in the stream, many will not. It is * never correct to use the return value of this method to allocate * a buffer intended to hold all data in this stream. * * <p> A subclass' implementation of this method may choose to throw an * {@link IOException} if this input stream has been closed by * invoking the {@link #close()} method. * * <p> The {@code available} method for class {@code InputStream} always * returns {@code 0}. * * <p> This method should be overridden by subclasses. * * @return an estimate of the number of bytes that can be read (or skipped * over) from this input stream without blocking or {@code 0} when * it reaches the end of the input stream. * @exception IOException if an I/O error occurs. */ public int available() throws IOException { return 0; } /** * Closes this input stream and releases any system resources associated * with the stream. * * <p> The <code>close</code> method of <code>InputStream</code> does * nothing. * * @exception IOException if an I/O error occurs. */ public void close() throws IOException {} /** * Marks the current position in this input stream. A subsequent call to * the <code>reset</code> method repositions this stream at the last marked * position so that subsequent reads re-read the same bytes. * * <p> The <code>readlimit</code> arguments tells this input stream to * allow that many bytes to be read before the mark position gets * invalidated. * * <p> The general contract of <code>mark</code> is that, if the method * <code>markSupported</code> returns <code>true</code>, the stream somehow * remembers all the bytes read after the call to <code>mark</code> and * stands ready to supply those same bytes again if and whenever the method * <code>reset</code> is called. However, the stream is not required to * remember any data at all if more than <code>readlimit</code> bytes are * read from the stream before <code>reset</code> is called. * * <p> Marking a closed stream should not have any effect on the stream. * * <p> The <code>mark</code> method of <code>InputStream</code> does * nothing. * * @param readlimit the maximum limit of bytes that can be read before * the mark position becomes invalid. * @see java.io.InputStream#reset() */ public synchronized void mark(int readlimit) {} /** * Repositions this stream to the position at the time the * <code>mark</code> method was last called on this input stream. * * <p> The general contract of <code>reset</code> is: * * <p>[list] * * <li> If the method <code>markSupported</code> returns * <code>true</code>, then: * * [list]<li> If the method <code>mark</code> has not been called since * the stream was created, or the number of bytes read from the stream * since <code>mark</code> was last called is larger than the argument * to <code>mark</code> at that last call, then an * <code>IOException</code> might be thrown. * * <li> If such an <code>IOException</code> is not thrown, then the * stream is reset to a state such that all the bytes read since the * most recent call to <code>mark</code> (or since the start of the * file, if <code>mark</code> has not been called) will be resupplied * to subsequent callers of the <code>read</code> method, followed by * any bytes that otherwise would have been the next input data as of * the time of the call to <code>reset</code>. [/list] * * <li> If the method <code>markSupported</code> returns * <code>false</code>, then: * * [list]<li> The call to <code>reset</code> may throw an * <code>IOException</code>. * * <li> If an <code>IOException</code> is not thrown, then the stream * is reset to a fixed state that depends on the particular type of the * input stream and how it was created. The bytes that will be supplied * to subsequent callers of the <code>read</code> method depend on the * particular type of the input stream. [/list][/list] * * <p>The method <code>reset</code> for class <code>InputStream</code> * does nothing except throw an <code>IOException</code>. * * @exception IOException if this stream has not been marked or if the * mark has been invalidated. * @see java.io.InputStream#mark(int) * @see java.io.IOException */ public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); } /** * Tests if this input stream supports the <code>mark</code> and * <code>reset</code> methods. Whether or not <code>mark</code> and * <code>reset</code> are supported is an invariant property of a * particular input stream instance. The <code>markSupported</code> method * of <code>InputStream</code> returns <code>false</code>. * * @return <code>true</code> if this stream instance supports the mark * and reset methods; <code>false</code> otherwise. * @see java.io.InputStream#mark(int) * @see java.io.InputStream#reset() */ public boolean markSupported() { return false; } }
//OutputStream,从socket获取的输出流,需要BufferedOutputStream,DataOutputStream //的包装才可以发送数据,注意,flush函数,将flush函数调用是,立即发送缓冲区里的所有数//据 package java.io; /** * This abstract class is the superclass of all classes representing * an output stream of bytes. An output stream accepts output bytes * and sends them to some sink. * <p> * Applications that need to define a subclass of * <code>OutputStream</code> must always provide at least a method * that writes one byte of output. * * @author Arthur van Hoff * @see java.io.BufferedOutputStream * @see java.io.ByteArrayOutputStream * @see java.io.DataOutputStream * @see java.io.FilterOutputStream * @see java.io.InputStream * @see java.io.OutputStream#write(int) * @since JDK1.0 */ public abstract class OutputStream implements Closeable, Flushable { /** * Writes the specified byte to this output stream. The general * contract for <code>write</code> is that one byte is written * to the output stream. The byte to be written is the eight * low-order bits of the argument <code>b</code>. The 24 * high-order bits of <code>b</code> are ignored. * <p> * Subclasses of <code>OutputStream</code> must provide an * implementation for this method. * * @param b the <code>byte</code>. * @exception IOException if an I/O error occurs. In particular, * an <code>IOException</code> may be thrown if the * output stream has been closed. */ public abstract void write(int b) throws IOException; /** * Writes <code>b.length</code> bytes from the specified byte array * to this output stream. The general contract for <code>write(b)</code> * is that it should have exactly the same effect as the call * <code>write(b, 0, b.length)</code>. * * @param b the data. * @exception IOException if an I/O error occurs. * @see java.io.OutputStream#write(byte[], int, int) */ public void write(byte b[]) throws IOException { write(b, 0, b.length); } /** * Writes <code>len</code> bytes from the specified byte array * starting at offset <code>off</code> to this output stream. * The general contract for <code>write(b, off, len)</code> is that * some of the bytes in the array <code>b</code> are written to the * output stream in order; element <code>b[off]</code> is the first * byte written and <code>b[off+len-1]</code> is the last byte written * by this operation. * <p> * The <code>write</code> method of <code>OutputStream</code> calls * the write method of one argument on each of the bytes to be * written out. Subclasses are encouraged to override this method and * provide a more efficient implementation. * <p> * If <code>b</code> is <code>null</code>, a * <code>NullPointerException</code> is thrown. * <p> * If <code>off</code> is negative, or <code>len</code> is negative, or * <code>off+len</code> is greater than the length of the array * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> is thrown. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. * @exception IOException if an I/O error occurs. In particular, * an <code>IOException</code> is thrown if the output * stream is closed. */ public void write(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } for (int i = 0 ; i < len ; i++) { write(b[off + i]); } } /** * Flushes this output stream and forces any buffered output bytes * to be written out. The general contract of <code>flush</code> is * that calling it is an indication that, if any bytes previously * written have been buffered by the implementation of the output * stream, such bytes should immediately be written to their * intended destination. * <p> * If the intended destination of this stream is an abstraction provided by * the underlying operating system, for example a file, then flushing the * stream guarantees only that bytes previously written to the stream are * passed to the operating system for writing; it does not guarantee that * they are actually written to a physical device such as a disk drive. * <p> * The <code>flush</code> method of <code>OutputStream</code> does nothing. * * @exception IOException if an I/O error occurs. */ public void flush() throws IOException { } /** * Closes this output stream and releases any system resources * associated with this stream. The general contract of <code>close</code> * is that it closes the output stream. A closed stream cannot perform * output operations and cannot be reopened. * <p> * The <code>close</code> method of <code>OutputStream</code> does nothing. * * @exception IOException if an I/O error occurs. */ public void close() throws IOException { } }
//BufferedInputStream package java.io; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; /** * A <code>BufferedInputStream</code> adds * functionality to another input stream-namely, * the ability to buffer the input and to * support the <code>mark</code> and <code>reset</code> * methods. When the <code>BufferedInputStream</code> * is created, an internal buffer array is * created. As bytes from the stream are read * or skipped, the internal buffer is refilled * as necessary from the contained input stream, * many bytes at a time. The <code>mark</code> * operation remembers a point in the input * stream and the <code>reset</code> operation * causes all the bytes read since the most * recent <code>mark</code> operation to be * reread before new bytes are taken from * the contained input stream. * * @author Arthur van Hoff * @since JDK1.0 */ public class BufferedInputStream extends FilterInputStream { private static int defaultBufferSize = 8192;
//BufferedOutputStream package java.io; /** * The class implements a buffered output stream. By setting up such * an output stream, an application can write bytes to the underlying * output stream without necessarily causing a call to the underlying * system for each byte written. * * @author Arthur van Hoff * @since JDK1.0 */ public class BufferedOutputStream extends FilterOutputStream {
//DataInputStream package java.io; /** * A data input stream lets an application read primitive Java data * types from an underlying input stream in a machine-independent * way. An application uses a data output stream to write data that * can later be read by a data input stream. * <p> * DataInputStream is not necessarily safe for multithreaded access. * Thread safety is optional and is the responsibility of users of * methods in this class. * * @author Arthur van Hoff * @see java.io.DataOutputStream * @since JDK1.0 */ public class DataInputStream extends FilterInputStream implements DataInput {
//DataOutputStream package java.io; /** * A data output stream lets an application write primitive Java data * types to an output stream in a portable way. An application can * then use a data input stream to read the data back in. * * @author unascribed * @see java.io.DataInputStream * @since JDK1.0 */ public class DataOutputStream extends FilterOutputStream implements DataOutput {
//FilterInputStream
//FilterOutputStream
发表评论
-
文件通道解析二(文件锁,关闭通道)
2017-05-16 23:17 1068文件通道解析一(读写操作,通道数据传输等):http://do ... -
文件通道解析一(读写操作,通道数据传输等)
2017-05-16 10:04 1164Reference定义(PhantomRefere ... -
文件通道创建方式综述
2017-05-15 17:39 1068Reference定义(PhantomReference,Cl ... -
文件读写方式简单综述后续(文件,流构造)
2017-05-14 23:04 1482Java Socket通信实例:http://donald-d ... -
文件读写方式简单综述
2017-05-14 11:13 1136Java Socket通信实例:http://donald-d ... -
FileChanne定义
2017-05-12 23:28 938文件读写方式简单综述:http://donald-draper ... -
SeekableByteChannel接口定义
2017-05-11 08:43 1237ByteChannel,分散聚集通道接口的定义(SocketC ... -
FileChannel示例
2017-05-11 08:37 994前面我们看过socket通道,datagram通道,以管道Pi ... -
PipeImpl解析
2017-05-11 08:41 935ServerSocketChannel定义:http://do ... -
Pipe定义
2017-05-10 09:07 906Channel接口定义:http://donald-drape ... -
NIO-Pipe示例
2017-05-10 08:47 906PipeImpl解析:http://donald-draper ... -
DatagramChannelImpl 解析四(地址绑定,关闭通道等)
2017-05-10 08:27 781DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析三(多播)
2017-05-10 08:20 1902DatagramChannelImpl 解析一(初始化):ht ... -
NIO-UDP实例
2017-05-09 12:32 1587DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析二(报文发送与接收)
2017-05-09 09:03 1407DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析一(初始化)
2017-05-08 21:52 1411Channel接口定义:http://donald-drape ... -
MembershipKeyImpl 简介
2017-05-08 09:11 925MembershipKey定义:http://donald-d ... -
DatagramChannel定义
2017-05-07 23:13 1229Channel接口定义:http://donald-drape ... -
MulticastChanne接口定义
2017-05-07 13:45 1137NetworkChannel接口定义:ht ... -
MembershipKey定义
2017-05-06 16:20 918package java.nio.channels; i ...
相关推荐
Python与Java间Socket通信实例代码详解 Python与Java间Socket通信是指在Python和Java两个不同的语言平台之间实现数据交换和通信的过程。Socket是Python和Java中都支持的网络通信机制,可以实现跨语言平台的通信。 ...
在Android平台上进行网络通信时,Socket通信是一种常见且重要的方式,尤其在实现设备间的数据交换、服务器客户端交互等场景。本实例程序主要涉及到的是Android应用如何利用Socket进行TCP(Transmission Control ...
在Android平台上进行网络通信时,Socket通信是一种常见且重要的方式,尤其在实现设备间的数据传输、服务器客户端交互等场景。本实例程序主要关注TCP Socket,它是一种面向连接、可靠的网络通信协议,确保数据的顺序...
Java Socket通信实现是一种基于TCP/IP协议的网络通信方式,它允许两台计算机通过互联网进行双向数据传输。在Java中,Socket类和ServerSocket类是实现客户端-服务器模型通信的核心工具。下面将详细介绍Java Socket...
这个"Java Socket使用实例"提供了一个基础的网络通信模板,通过学习和实践,你可以进一步了解Socket通信的原理,掌握在网络环境下进行数据交换的方法。在实际项目中,Socket通信常用于构建分布式系统、实时聊天应用...
在这个实例中,我们将探讨如何使用Java和Visual Basic(VB)来实现Socket通信。下面我们将详细讲解相关知识点。 1. **Socket基本概念** - Socket,也称为套接字,是网络通信中的一个抽象概念,它是进程间通信(IPC...
在Java编程领域,Socket通信是实现网络间应用进程间通信的一种技术。本示例将深入讲解如何使用Java Socket进行编码,结合CINDY开源包,为开发者提供实用的开发指导。 首先,理解Java Socket的基本概念至关重要。...
【Java实现基于TCP协议的简单Socket通信实例】 在Java中,TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。Socket是Java中实现网络通信的基本接口,它允许两台计算机通过TCP/IP进行通信...
以上就是Android平台上的简单Socket通信实例,包括数据的发送、接收、解析,以及UI的更新。实际项目中,可能还需要考虑网络状态的变化、重试机制、线程同步等问题,以确保通信的稳定性和用户体验。通过不断学习和...
Java Socket通信实现是Java网络编程中的重要组成部分,它允许两台计算机通过TCP/IP协议进行双向通信。在Java中,Socket提供了低级别的、基于连接的、面向数据流的通信API,可以用于实现客户端-服务器架构的应用程序...
在IT领域,网络编程是构建分布式系统的关键技术之一,...理解并实践这个Android和电脑Socket通信实例,开发者可以深入学习Android的网络编程,这对于开发涉及远程数据交换的应用至关重要,如即时通讯、文件传输等场景。
Java Socket通信是网络编程中的基础概念,主要用于实现客户端与服务器之间的双向通信。在这个"JAVA Socket通信示例"中,我们可能会看到如何通过Socket类来创建连接,实现数据的单工、半双工和全双工传输。下面我们将...
在这个"Java Socket 通信服务与客户端完整示例"中,我们可以深入理解Socket通信的原理以及如何在实际项目中应用。 1. **Socket基本概念** - **ServerSocket**: 服务器端使用的类,用于监听客户端的连接请求。 - *...
学习这些Java Socket编程实例,有助于理解TCP/IP通信的基本原理,为构建实际的网络应用程序打下坚实的基础。你可以通过调试和修改`SocketTest`代码,进一步探索和实践Socket编程的不同场景,如文件传输、聊天应用等...
Java和C++之间的Socket通信是跨语言网络编程的一个常见应用场景,尤其在系统集成、设备通讯或者混合编程中。Socket提供了一种基于TCP/IP协议的进程间通信(IPC)方式,可以实现在不同操作系统上的进程之间的数据传输...
Java实现的简单Socket通信是网络编程中的基础技术,主要用于设备间的双向数据传输。在这个场景中,我们有两个窗口,一个作为服务器端,另一个作为客户端,它们通过TCP协议进行通信。TCP是一种面向连接的、可靠的传输...
在Java开发中,Socket编程是一种常见的网络通信方式,它允许不同计算机上的应用程序通过网络进行交互。然而,对于涉及敏感信息的应用场景,如金融交易、个人隐私数据处理等,仅仅依靠Socket的基础功能是远远不够的,...
Java Socket通信是网络编程中的基础概念,主要用于两个应用程序之间的双向通信。在这个"Java_socket 通信示例"中,我们看到的是一个简单的聊天室应用,它利用了Java的Socket API来实现实时的数据交换。以下是对这个...
Java Socket通信是网络编程中的基础概念,主要用于两台计算机之间的数据传输。Socket在Java中被封装为类,提供了客户端和服务器端进行双向通信的能力。在这个"java Socket通信实现.zip"的压缩包中,可能包含了关于...
Java Socket通信是网络编程中的重要一环,它提供了在两台计算机之间建立低级连接的能力,使得它们可以相互通信。在这个"java上socket通信即时通信界面本"中,我们很显然关注的是如何使用Java来构建一个具有图形用户...