嗨,谢谢你。
目前,我正在尝试让我的TCP程序从目录(这是服务器端)读取文件,然后将该文件发送到请求它的套接字(客户端)。
这是我的代码:
服务器端:
File FileList = new File(".....filepath....");
Scanner scan = new Scanner(FileList);
//idToFile just searching for the name of the file the client asked for
String TheName = idToFile(Integer.toString(result));
//Opens the chosen file such as an image to be used
File myImageFile = new File("....filepath...." + TheName);
//sendResponse is a function with a writeUTF (but only works for strings)
sendResponse("#OK");
sendResponse(TheName);
sendResponse(Long.toString(myImageFile.length()));
//This line causes the error and says that it expected a string and not a file
output.writeUTF(myImageFile);
private void sendResponse(String response)
{
try
{
output.writeUTF(response);
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
客户方:
ClientHandler client = new ClientHandler();
//getResponse just catches the written strings, but it can't work with a file either
String TheMessage = client.getResponse();
String Name = client.getResponse();
long FileSize = Long.parseLong(client.getResponse());
以下是ClientHandler的代码:
public class ClientHandler
{
private static int port = 2016;
private DataInputStream input;
private DataOutputStream output;
private Socket cSocket;
public ClientHandler()
{
cSocket = null;
try
{
cSocket = new Socket("localhost", port); //connecting to the server
System.out.println("Client is connected on port " + port);
output = new DataOutputStream(cSocket.getOutputStream());
input = new DataInputStream(cSocket.getInputStream());
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
public void sendMessage(String message) //checking if the message is sent
{
try
{
output.writeUTF(message);
output.flush();
System.out.println("Message sent to the server");
}
catch (IOException e)
{
e.printStackTrace();
}
}
public String getResponse()
{
String msg = "";
try
{
msg = input.readUTF();
}
catch(IOException ex)
{
ex.printStackTrace();
}
return msg;
}
}
那么如何使用DataOutputStream将任何类型的文件从我的服务器发送到我的客户端,以及我的客户端如何使用DataInputStream捕获该文件并将其保存到磁盘?
谢谢。
答案 0 :(得分:1)
创建 DataOutputStream 和 DataInputStream 的新实例,如下所示。
#include<stdio.h>
main()
{
int arr[10], i, j, pairs = 0;
int n;
scanf("%d", &n);
for(i = 0; i<n; i++)
{
scanf("%d", &arr[i]);
}
for(i = 0; i<n; i++)
{
for(j = i+1; j<n; j++)
{
if(arr[i] == arr[j])
{
pairs++;
}
}
}
printf("%d", pairs);
}
对于示例代码,请检查显示in this lecture notes.
的示例类为了快速参考,以下是样本类的片段
select Product_Id, count(Product_Id) repeater
from mydatabase.dateofpurchase
where month(dateofpurchase) = 8
group by Product_Id
having count(Product_Id) =select max(x)
from (select count(Product_Id) as x
from mydatabase.dateofpurchase
where month(dateofpurchase) = 8
group by Product_Id) b
order by repeater desc ;
=========编辑1:阅读评论后
网络上的任何内容都是1和0,即字节。
假设您要将图像从一个服务器传输到另一个服务器,那么建议的方法是让服务器将文件内容读取为字节DataOutputStream socketOut = new DataOutputStream(socketObject.getOutputStream());
DataInputStream socketIn = new DataInputStream(socketObject.getInputStream());
并将其写入套接字。
在客户端,从套接字读取所有字节(在实际项目中使用BufferedReader)并将它们写入磁盘。您必须确保服务器和客户端都使用相同的编码。
使用BufferedInputStream和BufferedOutputStream而不是DataXXXStream。
这适用于任何文件类型 - mp3,mp4,jpeg,png,acc,txt,java。要使其在客户端系统中可用,请确保创建具有正确扩展名的文件。
答案 1 :(得分:0)
这是一个简单的服务器示例,它将二进制文件发送到每个客户端而无需进一步交互。
套接字提供输出流以将字节写入客户端。我们有一个文件“picin.jpg”我们要发送,所以我们需要将这个文件的每个字节写入套接字的输出流。为此,我们使用FileInputStream
包裹的BufferedInputStream
。
package networking;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress("localhost", 4711));
for(;;) {
Socket sock = ss.accept();
System.out.println("Connected to " + sock.getInetAddress());
try (
InputStream in = new BufferedInputStream(new FileInputStream("picin.jpg"));
OutputStream out = sock.getOutputStream();
)
{
int bytesSent = Util.copy(in, out);
System.out.println(String.format("%d bytes sent.", bytesSent));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
我将复制方法解压缩到util类,因为我们在客户端中需要完全相同。我们使用一个小字节数组作为缓冲区,并从一个流到另一个流复制一个接一个的块。
package networking;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Util {
public static int copy(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[2048];
int bytesRead = 0;
int totalBytes = 0;
while((bytesRead = in.read(buf)) != -1) {
totalBytes += bytesRead;
out.write(buf, 0, bytesRead);
}
return totalBytes;
}
}
客户端打开与服务器的连接,并将接收到的字节写入文件。套接字为输入流提供来自服务器的字节。我们使用FileOutputStream
包裹的BufferedOutputStream
来写入文件。我们使用相同的Util.copy()
方法将字节从一个流实际复制到另一个流。
package networking;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
try {
Socket sock = new Socket(InetAddress.getByName("localhost"), 4711);
try(
InputStream in = sock.getInputStream();
OutputStream out = new BufferedOutputStream(new FileOutputStream("picout.jpg"))
)
{
System.out.println("Connected to " + sock.getRemoteSocketAddress());
int bytesCopied = Util.copy(in, out);
System.out.println(String.format("%d bytes received", bytesCopied));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:try-with-ressources语句会自动关闭流。关闭插座,同时关闭相应的流。
Java 8包含一些便捷方法,用于将字节从文件复制到输出流或从输入流复制到文件。见java.nio.file.Files