Java IO之Socket通信
来源:互联网 发布:iptv管理系统源码下载 编辑:程序博客网 时间:2024/06/06 12:46
一、通讯协议TCP、UDP
Java Socket通信是基于TCP协议来完成的。讲Socket通信之前有必要先了解这两种底层协议。
TCP协议是面向连接、保证高可靠性(数据无丢失、数据无失序、数据无错误、数据无重复到达)传输层协议。TCP协议通过三次握手建立连接,四次握手断开连接,带重传功能的肯定确认来保证可靠传输。其中HTTP协议就是基于TCP协议来实现的。HTTP1.0默认短连接,HTTP1.1默认使用长连接,通过Keep-Alive来控制长连接时间,在同一个TCP连接中,只有上一个请求得到响应之后下一个请求才会发送。
UDP协议是无连接,不保证可靠的传输层协议。传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。
二、字符流和字节流
java在对文件、图片、视频等资源的操作上提供了字符流和字节流的操作方式,但是由于计算机中使用的是二进制来存储文件,而字符流对文件操作时会经历编码和解码阶段,所以字节流的操作要比字符流的操作效率高。但是字符流有很多操作都方便编程人员,对于文件的读取展现,我们可以使用字符流,免去了我们程序对字节和字符的转换。除此之外,字符流与字节流还有一个根本的区别。字节流不需要用到缓冲区,而字符流会先将数据放到缓存区再写入文件。如下例子,我们为了研究字符流和字节流是否用到缓冲区,不关闭输出流,因为在关闭输出流之前,会将缓冲区的内容全部输出,类似于调用flush()。
字节流:
package ioTest;import java.io.FileOutputStream;public class ByteTest { public static void main(String[] arg) { try { FileOutputStream fileOutputStream = new FileOutputStream("e:/ds2.txt"); fileOutputStream.write("hello world".getBytes()); //fileOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } }}
结果:文件ds2.txt显示【hello world】。
字符流:
package ioTest;import java.io.FileWriter;import java.io.IOException;public class CharTest { public static void main(String[] arg){ try { FileWriter fileWriter = new FileWriter("e:/ds.txt"); fileWriter.write("hello world"); //fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } }}
结果:文件ds.txt文件内容为空。
二进制I/O中常用的流操作类
InputStream:FileInputStream、FilterInputStream、ObjectInputStream。
FilterInputStream:DateInputStream、BufferedInputStream。
- FileInputStream以文件、文件名为构造函数创建输入流,是大部分输入流的起始点,其他输入流通过包装该输入流来进行操作。
- DateInputStream通过包装FileInputStream或其他字节输入流来构造,提供了多种数据读取方式,readByte()、readChar()、readInt()、readLine()、readUTF()等等。
- BufferedInputStream在读取文件时创建缓冲区,默认是512字节。
ObjectInputStream包含所有DateInputStream的功能,另外还增加了对对象的操作。
文本I/O中常见的流操作
BufferedReader、InputStreamReader、FileReader
- FileReader大部分字符流读取文件的起点。
- InputStreamReader连通字符流与字节流的枢纽,可以通过字节流来构造该字符流,然后通过其他字符流再包装该字符流,并且设置编码方式。如:
new BufferedReader(new InputStreamReader(new FileInputStream(fileName),"UTF-8"));
- BufferedReader在读取文件时创建缓冲区。
三、通信实现
前面介绍了相关的基础知识之后就直接上代码吧,另外对于多线程不太熟悉的朋友自己去补习一下。本程序包含三个类,具体的运行步骤在代码中做了详细的解释:
- SocketClient:socket通信客户端,运行时可以多次启动来模拟多个客户端。
- SocketServer:socket通信服务端,这里只有一个服务端,对于不同的客户端请求创建不同的线程来进行处理,通过线程池来进行管理。
- SocketThread:socket通信基础线程,供服务端调用,用于与客户端进行交互。
package socketTest;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;import java.util.Scanner;public class SocketClient { private DataOutputStream out;//通信输出流 private DataInputStream in;//通信输入流 private Socket socket; public static void main(String[] arg){ try { SocketClient socketClient = new SocketClient(); socketClient.initParam("127.0.0.1",6644); System.out.println("请输入向服务器发送的内容:"); socketClient.send(); } catch (Exception e) { e.printStackTrace(); } } //初始化参数 public void initParam(String ipAddress, int port) throws Exception{ this.socket = new Socket(ipAddress, port); this.out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); this.in = new DataInputStream(new BufferedInputStream(socket.getInputStream())); } //发送内容 public void send() throws IOException{ while(true){ Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); out.writeUTF(input); out.flush(); if("exit".equals(input)){ //获取服务器端断开连接的信息 String serverInput = in.readUTF(); System.out.println(serverInput); //客户端断开连接 System.out.println("客户端关闭连接"); in.close(); out.close(); socket.close(); break; } } }}
package socketTest;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class SocketServer{ private ServerSocket serverSocket; private ExecutorService threadPool; private static final int THREADCOUNT = 5; public static void main(String[] arg){ SocketServer socketServer = new SocketServer(); try { socketServer.initParam(6644); socketServer.getRequest(); } catch (Exception e) { socketServer.threadPool.shutdown(); e.printStackTrace(); } } //初始化参数 public void initParam(int port) throws Exception{ this.serverSocket = new ServerSocket(port); this.threadPool = Executors.newFixedThreadPool(THREADCOUNT); } //获取客户端请求 public void getRequest() throws IOException{ while (true) { Socket socket = this.serverSocket.accept(); SocketThread socketThread = new SocketThread(socket); threadPool.execute(socketThread); } }}
package socketTest;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;public class SocketThread implements Runnable { private Socket socket; private DataInputStream in;//通信输入流 private DataOutputStream out;//通信输出流 public SocketThread(Socket socket){ try { this.socket = socket; this.in = new DataInputStream(new BufferedInputStream(socket.getInputStream())); this.out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { String clientInput; while((clientInput = in.readUTF())!=null){ System.out.println(clientInput); if("exit".equals(clientInput)){ out.writeUTF("服务器已关闭连接"); out.close(); in.close(); socket.close(); System.out.println("服务端关闭连接"); break; } } } catch (IOException e) { e.printStackTrace(); } }}
- Java IO之Socket通信
- 【Node之web通信Socket.IO】
- Java NIO(异步IO)Socket通信例子
- java入门之Socket通信
- java回顾之socket通信
- java基础之Socket通信
- 通信模型socket.io
- socket.io -- 通信
- java.Socket。io通信,Unrecongnized Windows Sockets error:0:JVM_BIND
- java基础之socket io理解
- Java通信编程之Socket入门
- Flex和Java通信之Socket
- Java Socket实战之二 多线程通信
- Java Socket实战之二 多线程通信
- Java Socket实战之二 多线程通信 .
- Java Socket实战之二 多线程通信
- Java Socket实战之二 多线程通信
- Java Socket实战之二:多线程通信
- Mysql常用命令
- LeetCode 058 Length of Last Word
- 自定义Xcode插件实现
- Code::Blocks 12.11 error: ‘nullptr’ was not declared in this scope&GNU GCC -std=gnu++0x
- 达达日志收集系统
- Java IO之Socket通信
- Arborescent曲线
- mybatis不能插入,查询中文的问题以及可能的解决办法,以及Mysql数据库编码的设置
- Flume日志收集分层架构应用实践
- Git 笔记
- 可引导MBR的利用
- C++ error
- send() recv() 解析(转载)
- 自定义Toast及动画的二三事