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(); } }