我正在编写一个程序,使用套接字编程在客户端和服务器之间下载/上传文件。到目前为止,我编写的代码在一定程度上可以正常传输文件。但是,如果在进行下载/上载时由于网络/客户端/服务器中的问题导致连接失败。.我需要从原始点恢复下载/上载(不希望重新发送原始发送的数据)。我不确定该怎么做。我正在将文件读入字节数组并通过网络发送。我最初的想法是每次下载时..我应该检查文件是否已存在并将数据读入字节数组->将数据发送到服务器进行比较,然后通过以下方式返回服务器文件中的剩余数据:比较两个字节数组。但这似乎效率低下,并且取消了继续下载的意义(因为我再次发送了数据)。注意:文件名是唯一标识符。如果有人可以给我有关如何实现文件恢复html" target="_blank">功能的建议,我将不胜感激。
Server side code:
package servers;
import java.io.*;
import java.net.*;
import java.util.Arrays;
public class tcpserver1 extends Thread
{
public static void main(String args[]) throws Exception
{
ServerSocket welcomeSocket = null;
try
{
welcomeSocket = new ServerSocket(5555);
while(true)
{
Socket socketConnection = welcomeSocket.accept();
System.out.println("Server passing off to thread");
tcprunnable tcprunthread = new tcprunnable(socketConnection);
Thread thrd = new Thread(tcprunthread);
thrd.start();
System.out.println(thrd.getName());
}
}
catch(IOException e){
welcomeSocket.close();
System.out.println("Could not connect...");
}
}
}
class tcprunnable implements Runnable
{
Socket socke;
public tcprunnable(Socket sc){
socke = sc;
}
public void download_server(String file_name)
{
System.out.println("Inside server download method");
try
{
System.out.println("Socket port:" + socke.getPort());
//System.out.println("Inside download method of thread:clientsentence is:"+clientSentence);
// Create & attach output stream to new socket
OutputStream outToClient = socke.getOutputStream();
// The file name needs to come from the client which will be put in here below
File myfile = new File("D:\\ "+file_name);
byte[] mybytearray = new byte[(int) myfile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myfile));
bis.read(mybytearray, 0, mybytearray.length);
outToClient.write(mybytearray, 0, mybytearray.length);
System.out.println("Arrays on server:"+Arrays.toString(mybytearray));
outToClient.flush();
bis.close();
}
catch(FileNotFoundException f){f.printStackTrace();}
catch(IOException ie){
ie.printStackTrace();
}
}
public void upload_server(String file_name){
try{
byte[] mybytearray = new byte[1024];
InputStream is = socke.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream("D:\\ "+file_name);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
do {
baos.write(mybytearray);
bytesRead = is.read(mybytearray);
}
while (bytesRead != -1);
bos.write(baos.toByteArray());
System.out.println("Array on server while downloading:"+Arrays.toString(baos.toByteArray()));
bos.close();
}
catch(FileNotFoundException fe){fe.printStackTrace();}
catch(IOException ie){ie.printStackTrace();}
}
@Override
public void run()
{
try
{
System.out.println("Server1 up and running" + socke.getPort());
// Create & attach input stream to new socket
BufferedReader inFromClient = new BufferedReader
(new InputStreamReader(socke.getInputStream()));
// Read from socket
String clientSentence = inFromClient.readLine();
String file_name = inFromClient.readLine();
System.out.println("Sever side filename:" + file_name);
try{
if(clientSentence.equals("download"))
{
download_server(file_name);
}
else if(clientSentence.equals("upload"))
{
upload_server(file_name);
System.out.println("Sever side filename:" + file_name);
}
else
{
System.out.println("Invalid input");
}
}
catch(NullPointerException npe){
System.out.println("Invalid input!");
}
socke.close();
}
catch(IOException e)
{
e.printStackTrace();
System.out.println("Exception caught");
}
}
}
客户端代码:
package clients;
import java.io.*;
import java.net.*;
import java.util.Arrays;
public class tcpclient1
{
public static void main (String args[]) throws Exception
{
// Create input stream to send sentence to server
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = null;
while(true){
System.out.println("Please enter the server you want to use");
System.out.println("Enter 1 for Server 1 and 2 for Server2");
String server_choice = inFromUser.readLine();
if(server_choice.equals("1")){
// Create client socket to connect to server
// The server to use will be specified by the user
clientSocket = new Socket("localhost",5555);
break;
}
else if(server_choice.equals("2"))
{
clientSocket = new Socket("localhost",5556);
break;
}
else
{
System.out.println("Invalid entry");
}
}
System.out.println("Please enter download for dowloading");
System.out.println("Please enter upload for uploading");
// sentence is what'll be received from input jsp
String sentence = inFromUser.readLine();
if(sentence.equals("download"))
{
download_client(clientSocket,sentence);
}
else if(sentence.equals("upload"))
{
upload_client(clientSocket,sentence);
}
else
{
System.out.println("Invalid input");
}
clientSocket.close();
}
public static void download_client(Socket clientSocket , String sentence)
{
try{
// Create output stream attached to socket
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
// Send line to server
outToServer.writeBytes(sentence+'\n');
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the name of file to download:");
String file_to_download = inFromUser.readLine();
if(searching(file_to_download))
{
// Read local file and send that to the server for comparison
// DONT THINK THIS IS THE RIGHT WAY TO GO ABOUT THINGS SINCE IT BEATS THE PURPOSE OF RESUMING A DOWNLOAD/UPLOAD
}
// Send filetodownload to server
outToServer.writeBytes(file_to_download+'\n');
byte[] mybytearray = new byte[1024];
InputStream is = clientSocket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream("E:\\ "+file_to_download);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
do {
baos.write(mybytearray);
bytesRead = is.read(mybytearray);
}
while (bytesRead != -1);
bos.write(baos.toByteArray());
System.out.println("Array on client while downloading:"+Arrays.toString(baos.toByteArray()));
bos.close();
}
catch(FileNotFoundException fe){fe.printStackTrace();}
catch(IOException ie){ie.printStackTrace();}
}
public static void upload_client(Socket clientSocket, String sentence)
{
try{
// Create output stream attached to socket
DataOutputStream outToServer1 = new DataOutputStream(clientSocket.getOutputStream());
// Send line to server
outToServer1.writeBytes(sentence+'\n');
System.out.println("In the client upload method");
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the name of file to upload:");
String file_to_upload = inFromUser.readLine();
//System.out.println("Cline side file name:"+file_to_upload);
outToServer1.writeBytes(file_to_upload+'\n');
System.out.println(file_to_upload);
OutputStream outtoserver = clientSocket.getOutputStream();
File myfile = new File("E:\\ "+file_to_upload);
byte[] mybytearray = new byte[(int) myfile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myfile));
bis.read(mybytearray, 0, mybytearray.length);
outtoserver.write(mybytearray, 0, mybytearray.length);
System.out.println("filename:"+file_to_upload+"Arrays on client while uploading:"+Arrays.toString(mybytearray));
outtoserver.flush();
bis.close();
}
catch(FileNotFoundException fe){fe.printStackTrace();}
catch(IOException ie){ie.printStackTrace();}
}
public static boolean searching(String file_name)
{
String file_path = "E:\\ "+file_name;
File f = new File(file_path);
if(f.exists() && !f.isDirectory()) { return true; }
else
return false;
}
}
上面的代码可以很好地在客户端和服务器之间传输文件。
再次,非常感谢您的帮助!
您可以通过多种方式执行此操作,建议您向服务器创建一个单独的请求类型,以接受文件名和文件位置(即文件在文件中连接失败的位置)。
这就是从客户端的服务器获取文件的方式:
int filePosition = 0;
InputStream is = clientSocket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
do {
baos.write(mybytearray);
bytesRead = is.read(mybytearray);
if(bytesRead != -1)
filePosition += bytesRead;
}
while (bytesRead != -1);
现在,如果由于某种原因连接中断,您可以使用相同的文件名和 filePosition 再次向服务器发送请求,服务器将像下面这样发送文件:
OutputStream outToClient = socke.getOutputStream();
// The file name needs to come from the client which will be put in here below
File myfile = new File("D:\\ "+file_name);
byte[] mybytearray = new byte[(int) myfile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myfile));
bis.skip(filePosition) //Advance the stream to the desired location in the file
bis.read(mybytearray, 0, mybytearray.length);
outToClient.write(mybytearray, 0, mybytearray.length);
System.out.println("Arrays on server:"+Arrays.toString(mybytearray));
outToClient.flush();
bis.close();
在客户端中,您可以打开文件流,并append = true
在构造函数中指定如下所示:
FileOutputStream fos = new FileOutputStream("D:\\ "+file_name, true);
这可能是实现此目的的一种方法,还有很多选择。我还建议在传输后使用诸如MD5之类的哈希函数来验证文件,例如,它为给定的输入创建唯一的标记,并且对于相同的输入始终输出相同的结果,这意味着您可以从同一文件创建标记在服务器和客户端中,如果文件确实相同,它将生成相同的标记。由于图章的大小相对于它自己的文件来说很小,并且它也是固定的,因此可以在客户端/服务器之间发送它而没有太多开销。
您可以使用以下代码生成MD5哈希值:
MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream is = Files.newInputStream(Paths.get("file.txt"))) {
DigestInputStream dis = new DigestInputStream(is, md);
/* Read stream to EOF as normal... */
}
byte[] digest = md.digest();
问题内容: 检测插座是否已掉落的最合适方法是什么?还是实际上是否发送过数据包? 我有一个库,用于通过Apple网关(在GitHub上提供)将Apple Push Notifications发送到iPhone 。客户端需要打开一个套接字并发送每个消息的二进制表示形式。但不幸的是,Apple不会返回任何确认。该连接也可以重用于发送多个消息。我正在使用简单的Java套接字连接。相关代码为: 在某些情况下
问题内容: 我正在使用OpenShift和WildFly 8.2.1 final来实现新的HTML5 websocket。我使用了本教程来设置这个项目。 每当我打开MyTest.html时,这就是JavaScript记录的内容: 服务器连接,然后立即断开连接。为什么?我究竟做错了什么?有什么我想念的吗? 这是模式代码-> serverendpoint.java MyTest.html: 和pom.
在代理上使用HTTP隧道时,TCP套接字有问题。 客户端(C++)打开到服务器(JAVA)的TCP套接字。我添加了对HTTP代理的支持。一切正常,客户端发送“HTTP Connect”请求如下所示,并在以下情况下继续普通TCP连接: 然而,如果代理中配置了空闲超时,并且没有发送实际数据,则尽管客户端每60秒发送TCP保持活动数据包,但连接将终止。空闲超时配置为10分钟。
我编写了简单的服务器/客户端程序,其中客户端将一些硬编码数据以小块形式发送给服务器程序,服务器程序正在等待数据,以便将其打印到终端。在客户端,我在循环中调用send(),同时有更多的数据要发送,而在服务器上,我使用read()执行同样的操作,即返回的字节数为 如果我在完成发送后专门在客户端的套接字上调用close(),那么这个示例非常有效,但如果我不这样做,服务器将不会实际退出read()循环,直
问题内容: 大家好。我有一个使用ServerSocket和Socket类用Java编写的服务器。 我希望能够检测并处理断开连接,然后在必要时重新连接新客户端。 检测客户端断开连接,关闭套接字然后接受新客户端的正确步骤是什么? 问题答案: 大概是在从套接字读取数据,也许是在输入流上使用包装器,例如BufferedReader。在这种情况下,当相应的读取操作返回-1(对于原始read()调用)或为nu
我的用例是周期性地轮询本地目录中的新文件列表,然后将它们上传到1个连接中的FTP服务器。Camel路由在Spring XML中定义如下: