使用 UDP 在服务器和客户端之间传输文件(.png、.txt)
File transfer (.png , .txt) between Server and Client using UDP
我写了一个服务器和客户端让客户端连接到服务器,select一个来自服务器目录的数据用 UDP 协议传输数据,但问题是,它只适用于 .txt 文件它不适用于 .png 文件,并且在 .txt 文件中,输出文件与原始文件不同,例如单词之间的行不存在,并且所有单词并排打印而不是逐行打印。我该如何解决这个问题?
服务器端:
import java.io.*;
import java.net.*;
public class FTPServer {
public static void main(String[] args)
{
DatagramSocket socket = null;
DatagramPacket inPacket = null;
DatagramPacket outPacket = null;
byte[] inBuf, outBuf;
String msg;
final int PORT = 50000;
try
{
socket = new DatagramSocket(PORT);
while(true)
{
System.out.println("\nRunning...\n");
inBuf = new byte[1000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
int source_port=inPacket.getPort();
InetAddress source_address = inPacket.getAddress();
msg = new String(inPacket.getData(), 0, inPacket.getLength());
System.out.println("CLient: " + source_address + ":" + source_port);
String dirname = "/home/erke/Desktop/data";
File f1 = new File(dirname);
File fl[] = f1.listFiles();
StringBuilder sb = new StringBuilder("\n");
int c=0;
for(int i = 0;i<fl.length;i++)
{
if(fl[i].canRead())
c++;
}
sb.append(c+ " files found.\n\n");
for(int i=0; i<fl.length;i++)
sb.append(fl[i].getName()+ " " + fl[i].length()+ " Bytes\n");
sb.append("\nEnter file name to Download: ");
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, source_address, source_port);
socket.send(outPacket);
inBuf = new byte[1000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String filename = new String(inPacket.getData(), 0, inPacket.getLength());
System.out.println("Requested File: " + filename);
boolean flis = false;
int index =-1;
sb = new StringBuilder("");
for(int i=0;i<fl.length;i++)
{
if(((fl[i].getName()).toString()).equalsIgnoreCase(filename))
{
index = i;
flis = true;
}
}
if(!flis)
{
System.out.println("ERROR");
sb.append("ERROR");
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, source_address, source_port);
socket.send(outPacket);
}
else
{
try
{
//File send
File ff=new File(fl[index].getAbsolutePath());
FileReader fr = new FileReader(ff);
BufferedReader brf = new BufferedReader(fr);
String s = null;
sb=new StringBuilder();
while((s=brf.readLine())!=null)
{
sb.append(s);
}
if(brf.readLine()==null)
System.out.println("File Read Succesfull, CLosing Socket");
outBuf=new byte[100000];
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length,source_address, source_port);
socket.send(outPacket);
} catch (Exception ioe) {
System.out.println(ioe);
}
}
}
} catch (Exception e){
System.out.println("Error\n");
}
}
}
客户端:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class FTPClient {
public static void main(String[] args) {
DatagramSocket socket = null;
DatagramPacket inPacket = null;
DatagramPacket outPacket = null;
byte[] inBuf, outBuf;
final int PORT = 50000;
String msg = null;
Scanner src = new Scanner(System.in);
try
{
InetAddress address = InetAddress.getByName("127.0.0.1");
socket = new DatagramSocket();
msg = "";
outBuf =msg.getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length,address,PORT);
socket.send(outPacket);
inBuf = new byte[65535];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String data = new String(inPacket.getData(), 0, inPacket.getLength());
//Print file list
System.out.println(data);
//Send file name
String filename = src.nextLine();
outBuf = filename.getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, address, PORT);
socket.send(outPacket);
//Receive file
inBuf = new byte[100000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
data = new String(inPacket.getData(), 0, inPacket.getLength());
if(data.endsWith("ERROR"))
{
System.out.println("File doesn't exists.\n");
socket.close();
}
else
{
try
{
BufferedWriter pw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename)));
pw.write(data);
//Force write buffer to Fİle
pw.close();
System.out.println("File Write Succesful. Closing Socket");
socket.close();
} catch (Exception ioe) {
System.out.println("File Error\n");
socket.close();
}
}
} catch (Exception e) {
System.out.println("\nNetwork Error. Try Again Later. \n");
}
}
}
在您的代码中,您使用 String
在客户端和服务器中存储文件数据。为了能够传输除文本文件以外的任何文件,在您的服务器中您应该有一个 byte[]
缓冲区而不是 String
,并使用它来加载文件内容。您可以使用 类 和以 InputStream
结尾的名称来执行此操作。在你这样做之后通过网络发送这些字节。客户也是如此。
InputStream
和 OutputStream
用于直接来自文件的 read\write 字节,而 Reader
和 Writer
类 专门用于使用文本文件。这些 类 不能 read\write 字节,它们只适用于字符和字符串。不过,您仍然可以传输文本文件,因为它们也只是一个字节数组。
另外,如果您想在不丢失数据包的情况下传输文件,您应该使用 TCP,UDP 倾向于这样做,因为它没有像 TCP 那样确保数据包安全地传送到目的地的机制。
我写了一个服务器和客户端让客户端连接到服务器,select一个来自服务器目录的数据用 UDP 协议传输数据,但问题是,它只适用于 .txt 文件它不适用于 .png 文件,并且在 .txt 文件中,输出文件与原始文件不同,例如单词之间的行不存在,并且所有单词并排打印而不是逐行打印。我该如何解决这个问题?
服务器端:
import java.io.*;
import java.net.*;
public class FTPServer {
public static void main(String[] args)
{
DatagramSocket socket = null;
DatagramPacket inPacket = null;
DatagramPacket outPacket = null;
byte[] inBuf, outBuf;
String msg;
final int PORT = 50000;
try
{
socket = new DatagramSocket(PORT);
while(true)
{
System.out.println("\nRunning...\n");
inBuf = new byte[1000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
int source_port=inPacket.getPort();
InetAddress source_address = inPacket.getAddress();
msg = new String(inPacket.getData(), 0, inPacket.getLength());
System.out.println("CLient: " + source_address + ":" + source_port);
String dirname = "/home/erke/Desktop/data";
File f1 = new File(dirname);
File fl[] = f1.listFiles();
StringBuilder sb = new StringBuilder("\n");
int c=0;
for(int i = 0;i<fl.length;i++)
{
if(fl[i].canRead())
c++;
}
sb.append(c+ " files found.\n\n");
for(int i=0; i<fl.length;i++)
sb.append(fl[i].getName()+ " " + fl[i].length()+ " Bytes\n");
sb.append("\nEnter file name to Download: ");
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, source_address, source_port);
socket.send(outPacket);
inBuf = new byte[1000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String filename = new String(inPacket.getData(), 0, inPacket.getLength());
System.out.println("Requested File: " + filename);
boolean flis = false;
int index =-1;
sb = new StringBuilder("");
for(int i=0;i<fl.length;i++)
{
if(((fl[i].getName()).toString()).equalsIgnoreCase(filename))
{
index = i;
flis = true;
}
}
if(!flis)
{
System.out.println("ERROR");
sb.append("ERROR");
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, source_address, source_port);
socket.send(outPacket);
}
else
{
try
{
//File send
File ff=new File(fl[index].getAbsolutePath());
FileReader fr = new FileReader(ff);
BufferedReader brf = new BufferedReader(fr);
String s = null;
sb=new StringBuilder();
while((s=brf.readLine())!=null)
{
sb.append(s);
}
if(brf.readLine()==null)
System.out.println("File Read Succesfull, CLosing Socket");
outBuf=new byte[100000];
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length,source_address, source_port);
socket.send(outPacket);
} catch (Exception ioe) {
System.out.println(ioe);
}
}
}
} catch (Exception e){
System.out.println("Error\n");
}
}
}
客户端:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class FTPClient {
public static void main(String[] args) {
DatagramSocket socket = null;
DatagramPacket inPacket = null;
DatagramPacket outPacket = null;
byte[] inBuf, outBuf;
final int PORT = 50000;
String msg = null;
Scanner src = new Scanner(System.in);
try
{
InetAddress address = InetAddress.getByName("127.0.0.1");
socket = new DatagramSocket();
msg = "";
outBuf =msg.getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length,address,PORT);
socket.send(outPacket);
inBuf = new byte[65535];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String data = new String(inPacket.getData(), 0, inPacket.getLength());
//Print file list
System.out.println(data);
//Send file name
String filename = src.nextLine();
outBuf = filename.getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, address, PORT);
socket.send(outPacket);
//Receive file
inBuf = new byte[100000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
data = new String(inPacket.getData(), 0, inPacket.getLength());
if(data.endsWith("ERROR"))
{
System.out.println("File doesn't exists.\n");
socket.close();
}
else
{
try
{
BufferedWriter pw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename)));
pw.write(data);
//Force write buffer to Fİle
pw.close();
System.out.println("File Write Succesful. Closing Socket");
socket.close();
} catch (Exception ioe) {
System.out.println("File Error\n");
socket.close();
}
}
} catch (Exception e) {
System.out.println("\nNetwork Error. Try Again Later. \n");
}
}
}
在您的代码中,您使用 String
在客户端和服务器中存储文件数据。为了能够传输除文本文件以外的任何文件,在您的服务器中您应该有一个 byte[]
缓冲区而不是 String
,并使用它来加载文件内容。您可以使用 类 和以 InputStream
结尾的名称来执行此操作。在你这样做之后通过网络发送这些字节。客户也是如此。
InputStream
和 OutputStream
用于直接来自文件的 read\write 字节,而 Reader
和 Writer
类 专门用于使用文本文件。这些 类 不能 read\write 字节,它们只适用于字符和字符串。不过,您仍然可以传输文本文件,因为它们也只是一个字节数组。
另外,如果您想在不丢失数据包的情况下传输文件,您应该使用 TCP,UDP 倾向于这样做,因为它没有像 TCP 那样确保数据包安全地传送到目的地的机制。