我有一對一檔案傳輸的實體,一對多的訊息發送,但是我想要的是一對多的檔案傳輸,希望大神能幫我整合一下這兩段代碼,幫我達到我想要的效果。小白,跪求大神直接給代碼。
一、一對多訊息接收發送
接受多個客戶端:
package myjob1;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 基于TCP協議的Socket通信,實作用戶登陸
* 服務器端
*/
public class Server {
public static void main(String[] args) {
try {
//1.創建一個服務器端Socket,即ServerSocket,指定系結的埠,并監聽此埠
@SuppressWarnings("resource")
ServerSocket serverSocket=new ServerSocket(99);
Socket socket=null;
//記錄客戶端的數量
int count=0;
System.out.println("***服務器即將啟動,等待客戶端的連接***");
//回圈監聽等待客戶端的連接
while(true){
//呼叫accept()方法開始監聽,等待客戶端的連接
socket=serverSocket.accept();
//創建一個新的執行緒
ServerThread serverThread=new ServerThread(socket);
//啟動執行緒
serverThread.start();
count++;//統計客戶端的數量
System.out.println("客戶端的數量:"+count);
InetAddress address=socket.getInetAddress();
System.out.println("當前客戶端的IP:"+address.getHostAddress());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客戶端:
package myjob1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 客戶端
*/
public class Client {
public static void main(String[] args) {
try {
//1.創建客戶端Socket,指定服務器地址和埠
Socket socket=new Socket("localhost", 99);
//2.獲取輸出流,向服務器端發送資訊
OutputStream os=socket.getOutputStream();//位元組輸出流
PrintWriter pw=new PrintWriter(os);//將輸出流包裝為列印流
pw.write("用戶名:alice;密碼:789");
pw.flush();
socket.shutdownOutput();//關閉輸出流
//3.獲取輸入流,并讀取服務器端的回應資訊
InputStream is=socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String info=null;
while((info=br.readLine())!=null){
System.out.println("我是客戶端,服務器說:"+info);
}
//4.關閉資源
br.close();
is.close();
pw.close();
os.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、一對一檔案傳輸:
服務端:
package myjob2;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
// 選擇進行傳輸的檔案
// public Socket accept() throws
// IOException偵聽并接受到此套接字的連接。此方法在進行連接之前一直阻塞。
// 將檔案名及長度傳給客戶端。這里要真正適用所有平臺,例如中文名的處理,還需要加工,具體可以參見Think In Java
// 4th里有現成的代碼。
// 從包含的輸入流中讀取一定數量的位元組,并將它們存盤到緩沖區陣列 b
// 中。以整數形式回傳實際讀取的位元組數。在輸入資料可用、檢測到檔案末尾 (end of file)
// 或拋出例外之前,此方法將一直阻塞。
// 注意關閉socket鏈接哦,不然客戶端會等待server的資料過來,
// 直到socket超時,導致資料不完整。
public class ServerTest {
int port = 8821;
private ServerSocket ss;
void start() {
Socket s = null;
try {
ss = new ServerSocket(port);
while (true) {
// 選擇進行傳輸的檔案
String filePath = "D:\\lib.rar";
File fi = new File(filePath);
System.out.println("檔案長度:" + (int) fi.length());
// public Socket accept() throws
// IOException偵聽并接受到此套接字的連接。此方法在進行連接之前一直阻塞。
s = ss.accept();
System.out.println("建立socket鏈接");
DataInputStream dis = new DataInputStream(
new BufferedInputStream(s.getInputStream()));
dis.readByte();
DataInputStream fis = new DataInputStream(
new BufferedInputStream(new FileInputStream(filePath)));
DataOutputStream ps = new DataOutputStream(s.getOutputStream());
// 將檔案名及長度傳給客戶端。這里要真正適用所有平臺,例如中文名的處理,還需要加工,具體可以參見Think In Java
// 4th里有現成的代碼。
ps.writeUTF(fi.getName());
ps.flush();
ps.writeLong((long) fi.length());
ps.flush();
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
while (true) {
int read = 0;
if (fis != null) {
read = fis.read(buf);
// 從包含的輸入流中讀取一定數量的位元組,并將它們存盤到緩沖區陣列 b
// 中。以整數形式回傳實際讀取的位元組數。在輸入資料可用、檢測到檔案末尾 (end of file)
// 或拋出例外之前,此方法將一直阻塞。
}
if (read == -1) {
break;
}
ps.write(buf, 0, read);
}
ps.flush();
// 注意關閉socket鏈接哦,不然客戶端會等待server的資料過來,
// 直到socket超時,導致資料不完整。
fis.close();
s.close();
System.out.println("檔案傳輸完成");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String arg[]) {
new ServerTest().start();
}
}
客戶端:
package myjob2;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class ClientTest {
private ClientSocket cs = null;
private String ip = "localhost";// 設定成服務器IP
private int port = 8821;
private String sendMessage = "Windows";
public ClientTest() {
try {
if (createConnection()) {
sendMessage();
getMessage();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean createConnection() {
cs = new ClientSocket(ip, port);
try {
cs.CreateConnection();
System.out.print("連接服務器成功!" + "\n");
return true;
} catch (Exception e) {
System.out.print("連接服務器失敗!" + "\n");
return false;
}
}
private void sendMessage() {
if (cs == null)
return;
try {
cs.sendMessage(sendMessage);
} catch (Exception e) {
System.out.print("發送訊息失敗!" + "\n");
}
}
private void getMessage() {
if (cs == null)
return;
DataInputStream inputStream = null;
try {
inputStream = cs.getMessageStream();
} catch (Exception e) {
System.out.print("接收訊息快取錯誤\n");
return;
}
try {
// 本地保存路徑,檔案名會自動從服務器端繼承而來。
String savePath = "E:\\";
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
int passedlen = 0;
long len = 0;
savePath += inputStream.readUTF();
DataOutputStream fileOut = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(savePath)));
len = inputStream.readLong();
System.out.println("檔案的長度為:" + len + "\n");
System.out.println("開始接收檔案!" + "\n");
while (true) {
int read = 0;
if (inputStream != null) {
read = inputStream.read(buf);
}
passedlen += read;
if (read == -1) {
break;
}
// 下面進度條本為圖形界面的prograssBar做的,這里如果是打檔案,可能會重復列印出一些相同的百分比
System.out.println("檔案接收了" + (passedlen * 100 / len) + "%\n");
fileOut.write(buf, 0, read);
}
System.out.println("接收完成,檔案存為" + savePath + "\n");
fileOut.close();
} catch (Exception e) {
System.out.println("接收訊息錯誤" + "\n");
return;
}
}
public static void main(String arg[]) {
new ClientTest().getMessage();
}
}
uj5u.com熱心網友回復:
有沒有哪位大神會啊,小白很著急,希望大神會的話,能幫幫忙貼出來代碼看下,謝謝uj5u.com熱心網友回復:
你最后是怎么實作的呢?uj5u.com熱心網友回復:
把服務器改成多執行緒的不就好了?在里面添加個鏈表來保存客戶端的資訊,服務器每個子執行緒獨立處理客戶端來的請求就好了轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/109682.html
標籤:網絡通信
上一篇:Socket通信問題。
