项目中有使用到,Java利用socket连接到一台主机并向主机发送文件。也就是说有两台服务器a和b,要让a去主动连接b并且给b发送一个文件。
用到了socket和java io的知识。记录一下。
分为服务器端和客户端。这里服务器端是等待连接并接受文件的机器,客户端是连接服务器端并且发送文件的机器。
服务器端:
/** * server接受连接,接收文件 * * @author naughty * */ public class ServerTest { private int port = 8821; // 启动服务 private void start() { Socket s = null; try { ServerSocket ss = new ServerSocket(port); while (true) { s = ss.accept(); System.out.println("建立socket链接"); DataInputStream dis = new DataInputStream( new BufferedInputStream(s.getInputStream())); try { int bufferSize = 8192; byte[] buf = new byte[bufferSize]; String filename = dis.readUTF(); System.out.println("接收文件名 " + filename); DataOutputStream fileOut = new DataOutputStream( new BufferedOutputStream(new FileOutputStream( filename)));// 这个参数是保存路径 System.out.println("开始接收文件!" + "\n"); while (true) { int read = 0; if (dis != null) { read = dis.read(buf); } if (read == -1) { break; } fileOut.write(buf, 0, read); } System.out.println("接收完成。"); fileOut.close();dis.close(); } catch (Exception e) { System.out.println("接收消息错误" + "\n"); return; } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String arg[]) { new ServerTest().start(); } }
上面是服务器端的代码:
1、声明一个socket并且绑定本地机器的一个端口。
2、等待连接
3、获取socket的输入流
4、读取传送过来的文件名
5、声明一个文件输出流用于输出接收到的文件
6、从socket输入流读取数据,写入到文件输出流
7、关闭连接
-----------------------------------------------------------------------------
上面是服务器端的工作流程,下面看客户端的流程。
代码1(客户端代码):
import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.net.Socket; /** * 客户端发起连接 * * @author naughty * */ public class ClientSocket { private String ip; private int port; private Socket socket = null; DataOutputStream out = null; DataInputStream getMessageStream = null; public ClientSocket(String ip, int port) { this.ip = ip; this.port = port; } /** * 发送文件 * * @param filename * @throws IOException */ public void sendFile(String filename) throws IOException { out = new DataOutputStream(socket.getOutputStream());// 获取输出流 // 向输出流中写入文件 DataInputStream fis = new DataInputStream(new BufferedInputStream( new FileInputStream(filename))); // 写入文件名 out.writeUTF(filename); out.flush(); int bufferSize = 8192; byte[] buf = new byte[bufferSize]; while (true) { int read = 0; if (fis != null) { read = fis.read(buf); } if (read == -1) { break; } out.write(buf, 0, read); } out.flush(); // 关闭资源 out.close(); fis.close(); } /** * 创建socket连接 */ public void CreateConnection() throws Exception { try { socket = new Socket(ip, port); } catch (Exception e) { e.printStackTrace(); if (socket != null) socket.close(); throw e; } finally { } } public void shutDownConnection() { try { if (out != null) out.close(); if (getMessageStream != null) getMessageStream.close(); if (socket != null) socket.close(); } catch (Exception e) { e.printStackTrace(); } } }
clientsocket类负责发送文件。
代码2(测试代码):
public class ClientTest { private ClientSocket cs = null; private boolean createConnection(String ip, int port) { cs = new ClientSocket(ip, port); try { cs.CreateConnection(); System.out.print("连接服务器成功!" + "\n"); return true; } catch (Exception e) { System.out.print("连接服务器失败!" + "\n"); return false; } } // 发送请求,filename为文件路径 private void sendFile(String filename) { if (cs == null) return; try { cs.sendFile(filename); } catch (Exception e) { System.out.print("发送消息失败!" + "\n"); } } // 实现请求并接收 public void sendFile(String filename, String savePath, String host, int port, String username, String password) { if (this.createConnection(host, port)) { this.sendFile(filename); } } // 测试 public static void main(String arg[]) { ClientTest ct = new ClientTest(); ct.sendFile("c:\\b.png", "D:\\c.png", "192.168.169.133", 8821, "username", "password"); } }
客户端代码工作流程:
1、建立连接
2、获取socket的输出流,用于向其中写入要发送的文件名以及文件
3、关闭资源
-----------------------------------------------------------------------------------------------
看完了整体代码之后,可以对socket通信也有一个认识。
socket通信简单来讲,就是建立连接,然后得到相应的输入流或者输出流,从输入流中读取数据,向输出流中写入数据,就是这么一个过程。
follow me sina weibo @hello__佐小白__