Java如何利用Socket传输信息或文件
目录
- Socket
- 步骤
- 代码
- 优化
- 总结
本文中的是使用TCP协议进行文件传输
Socket
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。
套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
信息与文件传输使用C/S(Client/Server)。
步骤
- 1、启动服务端,等待客户端连接。
- 2、启动客户端连接服务端。
- 3、传输数据。
- 4、关闭客户端。
- 5、关闭服务端。
代码
首先启动服务端
package priv.zb.socket; import Java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class FileServer { @SuppressWarnings("resource") public static void main(String[] args) throws IOException { ServerSocket server = null; Socket socket = null; www.devze.com //向外界暴露一个端口9999的服务,默认IP为本机IP:127.0.0.1 server = new ServerSocket(9999); //返回一个Socket对象 socket = server.accept(); /** * * 启动服务端之后,会在 server.accept(); 方法处等待客户端的 * 连接,当启动客户端连接上服务端之后走过此方法运行后面的代码。 */ System.out.println("接收到客户端的连接"); //服务端向客户端发送消息 通过OutputStream //发出信息使用输出流OutputStream,接收信息使用输入咯InputStream OutputStream output = socket.getOutputStream(); //传输字符串 // byte[] bs = new byte[100]; // output.write("Hello".getBytes()); //传输文件 http://www.devze.com String filePath = "存放文件路径"; File file = new File(filePath ); byte[] fileBytes = new byte[100]; //定义文件每次发送大小 //读入到内存中,new 一个inputStream即可 //文件较大,不能一次性发送完毕,因此需要循环操作 InputStream fileIn = new FileInputStream(file); int len = -1; while((len = fileIn.read(fileBytes)) != -1) { output.write(fileBytes, 0, len); } //接受客户端消息 // InputStream in = socket.getInputStream(); // in.read(bs); // System.out.println("Server接收到信息:" + new String(bs)); System.out.println("发送成功"); output.close(); fileIn.csRREYFjlose(); } }
之后启动客户端
package priv.zb.socket; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class FileClient { @SuppressWarnings("resource") public static void main(String[] args) throws UnknownHostException, IOException { //建立连接 //客户端访问服务端发布的服务 Socket socket = new Socket("192.168.0.108",9999); //通过InputStream接收信息 InputStream input = socket.getInputStream(); byte[] fileBytes = new byte[100]; File file = new File("E:\\JAVA\\Java SE\\srcCopy.zip"); OutputStream output = new FileOutputStream(file); int len = -1; while( (len = input.read(fileBytes)) != -1) { output.write(fileBytes, 0, len); } //客户端接收到信息返回一个标识 // byte[] bs = new byte[100]; // input.read(bs); // System.out.println("Client 接收到消息:" + new String(bs)); //客户端向服务端发送一个消息 // OutputStream output = socket.getOutputStream(); // output.write("World".getBytes()); System.out.println("接收成功!!"); output.close(); input.close(); } }
这个代码在客户端连接一次之后,服务端便会主动关闭。
但是在实际的使用中一般不会只使用一次服务端,将会不断地重复连接服务端这一过程。
因此使用while(true)死循环来保持服务端的始终开启,利用多线程来解决这一问题。
优化
使用多线程是在服务端
服务端
package priv.zb.socket.runable; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class FileServer { @SuppressWarnings("resource") public static void main(String[] args) throws IOException { //向外界暴露一个端口9999的服务,默认IP为本机IP:127.0.0.1 ServerSocket server = new ServerSocket(9999); while(true) { Socket socket = server.accept(); //使用构造方法传入一个Socket对象与下载线程保持关联 new Thread(new MyDownload(socket)).start(); //下载线程 /* * MyDownload download = new MyDownload(socket); * //Runnable变为Thered对象 * new Thread(download).start(); */ } } }
下载线程:MyDownload.java
package priv.zb.socket.runable; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class MyDownload implements Runnable { //Mydownload.java与Server之间使用Socket对象联系 private Socket socket; public MyDownload(Socket socket) { this.socket = socket; } @Override public void run() { //返回一个Socket对象 OutputStream output =null; InputStream fileIn = null;http://www.devze.com try { System.out.println("接收到客户端的连接"); //服务端向客户端发送消息 通过OutputStream File file = new File("E:\\JAVA\\Java SE\\src.zip"); byte[] fileBytes = new byte[100]; //定义文件每次发送大小 //读入到内存中,new 一个inputStream即可 //文件较大,不能一次性发送完毕,因此需要循环操作 fileIn = new FileInputStream(file); int len = -1; output = socket.getOutputStream(); while((len = fileIn.read(fileBytes)) != -1) { output.write(fileBytes, 0, len); } System.out.println("发送成功"); } catch (IOException e1) { e1.printStackTrace(); } finally { try { if(output != null) output.close(); if(fileIn != null) fileIn.close(); } catch (IOException e) { android e.printStackTrace(); } } } }
之后即可多次传输信息不关闭服务端。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。
精彩评论