java套接字编程集成度很高,容易上手,客户端和服务器互传字符串的代码如下:
server:
package test1; /*tcp通信服务器端,接收客户端的请求,读取客户端发送的数据,回写数据 *服务器端必须明确:是哪个客户端请求的服务器,所以可以使用accept获取到请求的客户端对象 * 成员方法:accept(): * 返回的是socket * 服务器的实现步骤: * 1.创建服务器ServerSocket对象,和系统指定的端口对象 * 2.使用ServerSocket对象中的方法accept获取到请求的客户端对象Socket * 3.使用网络字节输入流对象读取客户端发送的数据 * 4.获取网络字节输出流getOutputStream, * 6.使用网络字节输出流中的方法write()给客户端回写数据 */ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class TcpServer { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(8888); Socket socket = server.accept(); InputStream is = socket.getInputStream(); byte[] bytes = new byte[1024]; int len = is.read(bytes); System.out.println(new String(bytes,0,len)); OutputStream os = socket.getOutputStream(); os.write("收到谢谢".getBytes()); //处理套接字关闭 socket.close(); //服务器端坚挺socket关闭 server.close(); } }
client:
package test1; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class TcpClient { public static void main(String[] args) throws IOException { // 服务器未运行在这个端口上的时候会抛出未连接异常 Socket socket = new Socket("127.0.0.1",8888); OutputStream os = socket.getOutputStream(); //获取服务器端的数据 os.write("你好服务器".getBytes()); //向服务器端写入数据 InputStream is = socket.getInputStream(); byte[] data = new byte[1024]; int len = is.read(data); System.out.println(new String(data,0,len)); socket.close(); } }
通过多线程上传文件的代码如下:
client:
package fileTransfre; import java.io.*; import java.net.Socket; public class TCPClient { public static void main(String[] args) throws IOException { //1.创建本地字节输入流绑定数据源 FileInputStream fis = new FileInputStream("C:\Users\lenovo\Desktop\20190824142136.jpg"); //2.创建客户端Socket对象,构造方法中指定了IP地址和端口号 Socket socket = new Socket("127.0.0.1",8888); //获取网络字节输出流对象 OutputStream os = socket.getOutputStream(); //使用本地字节输入流read方法读取本地图片,并且通过write方法向服务器传递 int len = 0; byte[] bytes = new byte[1024]; while((len = fis.read(bytes))!=-1){ os.write(bytes,0,len); } // 写入结束标记 socket.shutdownOutput(); // 读取服务器送过来的资源 InputStream is = socket.getInputStream(); while((len = is.read(bytes))!=-1){ System.out.println(new String(bytes,0,len)); } fis.close(); socket.close(); } }
server:
package fileTransfre; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.UUID; public class TCPServer { public static void main(String[] args) throws IOException { // 1.创建一个服务器端的监听套接字对象,指定响应的端口号 ServerSocket serverSocket = new ServerSocket(8888); // 2.获取请求的socket对象 // 让服务器一直处于监听状态,即死循环状态(accept是阻塞方法,知道产生连接才开始执行) while(true){ Socket socket = serverSocket.accept(); // 使用多线程技术对客户端请求进行线程分发,提高服务器的执行效率 // 在子线程中完成文件的上传 // 使用lambda表达式完成Runnable实例的创建 new Thread(() -> { try{ // 3.获取网络输入字节流 InputStream input = socket.getInputStream(); // 4.创建文件,判断文件夹是否存在,不存在则创建文件夹 File file = new File("C:\upload"); if(!file.exists()){ file.mkdir(); } String fileName = UUID.randomUUID().toString().replace("-","")+".jpg"; // 5.文件字节输出流,将文件输出到指定的目录下 FileOutputStream fos = new FileOutputStream(file+"\"+fileName); // 6.使用网络字节输入流读取客户端上传的文件 int len = 0; byte[] bytes = new byte[1024]; // 7.读取到的文件不是空的就将其写入文件中 // 服务器端不会接收到-1,因为客户端不会向服务器传输-1 while((len = input.read(bytes))!=-1){ fos.write(bytes,0,len); } // 7.向客户端回传数据 socket.getOutputStream().write("上传成功".getBytes()); System.out.println("服务器端上传成功"); }catch (Exception e) { e.printStackTrace(); } }).start(); } // 8.释放资源 // fos.close(); // serverSocket.close(); // input.close(); } }