gpt4 book ai didi

java - 如何处理客户端/服务器应用程序以发送消息和/或文件

转载 作者:行者123 更新时间:2023-12-02 06:45:56 24 4
gpt4 key购买 nike

我在这里进行了很多搜索,但没有找到任何符合我需要的内容。

我在客户端/服务器应用程序方面不是那么专家,这是我第一次尝试,所以,如果我犯了一些错误或者提出了愚蠢的问题,请耐心等待。

现在,回到我的问题..

我需要构建一个多客户端/服务器应用程序。

服务器端应该是客户端的简单管理器。

例如:

  • 服务器可以更改一些客户端参数
  • 接受来自客户端的文件
  • 其他无聊的东西..基本上可以翻译为发送字符串或发送文件或获取字符串和文件

另一方面,客户端是一个复杂的应用程序(至少对于用户而言),应该发送到服务器:

  • 一些用户注册数据(这里不需要安全性的东西,我已经对简单的客户端/服务器连接感到非常困惑)
  • 一个 PSD 文件,应该是用户工作的结果,因此当用户单击“我完成”时,应用程序会获取此 PSD 文件并将其发送到服务器用于存储目的
  • 其他客户端信息,例如默认配置数据等。

所以,我的问题基本上是这样的:如何处理服务器与特定客户端的通信?我的意思是,我已经启动了服务器,并且我只为一个客户端更改配置。

我想我需要以某种方式存储客户端..比如在数组(List)中,但我不知道这是否是正确的方法。(基本上我不知道SocketServerSocket类是如何工作的..如果这可以帮助您更好地理解)

此外,当服务器启动并监听时......需要更新 GUI 以显示新连接的客户端,因此我需要某种类型的服务器监听器,以便在新客户端显示时将操作触发回界面向上?(很多人使用 而(真){ 套接字=服务器.accept(); }方法,但这对我来说听起来不太聪明..)

这是基本的 Client.java 和 Server.java 文件,其中包含我根据大量 Google 搜索编写的客户端和服务器基本功能。

但是下面的所有代码并不能满足我的所有需求..

客户端.java

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client extends Socket {

private static Client instance = null;

/**
* The main init() function for this class, to create a Singleton instance for the Client
*
* @param host
* The host of the Server
* @param port
* The port of the Server
* @return The Client instance that is a new instance if no one exists previusly,
* otherwise an older instance is returned
* @throws UnknownHostException
* @throws IOException
*/
public static Client init( String host, Integer port ) throws UnknownHostException, IOException
{
if ( Client.instance == null )
Client.instance = new Client( host, port );
return Client.instance;
}

/**
* Default Constructor made private so this class can only be instantiated by the
* singleton init() function.
*
* @param host
* The host of the server
* @param port
* The port of the server
* @throws UnknownHostException
* @throws IOException
*/
private Client( String host, Integer port ) throws UnknownHostException, IOException
{
super( host, port );
}

/**
* Function used to send a file to the server.
* When this function fires, the Client class start sending a file to the server.
* Internally this function handles the filesize, and some other file information
* that the server needs to store the file in the correct location
*
* @param filename
* The filename of the file that will be sended to the server
*/
public void sendFile( String filename ) throws FileNotFoundException, IOException
{
// The file object from the filename
File file = new File( filename );

// A string object to build an half of the message that will be sent to the exceptions
StringBuilder exception_message = new StringBuilder();
exception_message.append( "The File [" ).append( filename ).append( "] " );

// Check if the file exists
if ( !file.exists() )
throw new FileNotFoundException( exception_message + "does not exists." );

// Check if the file size is not empty
if ( file.length() <= 0 )
throw new IOException( exception_message + "has zero size." );

// Save the filesize
Long file_size = file.length();

// Check if the filesize is something reasonable
if ( file_size > Integer.MAX_VALUE )
throw new IOException( exception_message + "is too big to be sent." );

byte[] bytes = new byte[file_size.intValue()];

FileInputStream fis = new FileInputStream( file );
BufferedInputStream bis = new BufferedInputStream( fis );
BufferedOutputStream bos = new BufferedOutputStream( this.getOutputStream() );

int count;

// Loop used to send the file in bytes group
while ( ( count = bis.read( bytes ) ) > 0 )
{
bos.write( bytes, 0, count );
}

bos.flush();
bos.close();
fis.close();
bis.close();
}

/**
* Function used to send string message from client to the server
*
* @param message
* The string message the server should get
* @throws IOException
*/
public void sendMessage( String message ) throws IOException
{
OutputStream os = this.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter( os );
BufferedWriter bw = new BufferedWriter( osw );

bw.write( message );
bw.flush();
}

/**
* Function used to get a message from the Server
*
* @return The message the server sent back
* @throws IOException
*/
public String getMessage() throws IOException
{
InputStream is = this.getInputStream();
InputStreamReader isr = new InputStreamReader( is );
BufferedReader br = new BufferedReader( isr );

String message = br.readLine();

return message;
}
}

服务器.java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server extends ServerSocket {

private static Server instance = null;
private Socket socket = null;

/**
*
* @param port
* @return
* @throws IOException
*/
public static Server init( Integer port ) throws IOException
{
if ( Server.instance == null )
Server.instance = new Server( port );
return Server.instance;
}

/**
*
* @param port
* @throws IOException
*/
private Server( Integer port ) throws IOException
{
super( port );

// Maybe this is something that needs to be improved
while ( true )
this.socket = this.accept();
}

/**
*
* @param message
* @throws IOException
*/
public void sendMessage( String message ) throws IOException
{
OutputStream os = this.socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter( os );
BufferedWriter bw = new BufferedWriter( osw );

bw.write( message );

bw.flush();
}

/**
*
* @return
* @throws IOException
*/
public String getMessage() throws IOException
{
InputStream is = this.socket.getInputStream();
InputStreamReader isr = new InputStreamReader( is );
BufferedReader br = new BufferedReader( isr );

String message = br.readLine();

return message;
}
}

嗯..请为我的英语道歉..请。

最佳答案

你的问题让我很好奇,现代的 java 方法会是什么样子。当我开始尝试套接字时,我也遇到了一些问题,所以这里有一个小例子应该可以帮助您解决问题。

服务器在自己的“线程”中处理每个客户端,你可以说这是基本的客户端/服务器架构。但我用的是新的Callable<V>而不是线程。

我没有延长Socket也不ServerSocket 。我以前从来没有见过这个。我认为在这种情况下,最好选择组合而不是继承。它为您提供了更多控制权,因为您可以委托(delegate)您喜欢的内容和方式。

有关更多信息,我建议您查看oracle tutorials .

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ClientServerExample
{
private final static int PORT = 1337;
private final static String LOOPBACK = "127.0.0.1";

public static void main(String[] args) throws IOException
{
ExecutorService se = Executors.newSingleThreadExecutor();
se.submit(new Server(PORT, 5));

ExecutorService ce = Executors.newFixedThreadPool(3);
for (String name : Arrays.asList("Anton", "John", "Lisa", "Ben", "Sam", "Anne"))
ce.submit(new Client(name, LOOPBACK, PORT));

ce.shutdown(); while (!ce.isTerminated()) {/* wait */}
se.shutdown();
}
}

class Client implements Callable<Void>
{
private final String name;
private final String ip;
private final int port;

public Client(String name, String ip, int port)
{
this.name = name;
this.ip = ip;
this.port = port;
}

@Override
public Void call() throws Exception
{
Socket s = new Socket(ip, port);
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
out.println("Hi, I'm " + name + "!");
out.close();
s.close();
return null;
}
}

class Server implements Callable<Void>
{
private final int port;
private final int clients;
private final ExecutorService e;

public Server(int port, int clients)
{
this.port = port;
this.clients = clients;
this.e = Executors.newFixedThreadPool(clients);
}

@Override
public Void call() throws Exception
{
ServerSocket ss = new ServerSocket(port);
int client = 0;
while (client < clients)
{
e.submit(new ClientHandler(client++, ss.accept()));
}
ss.close();
e.shutdown(); while (!e.isTerminated()) {/* wait */}
return null;
}
}

class ClientHandler implements Callable<Void>
{

private int client;
private Socket s;

public ClientHandler(int client, Socket s)
{
this.client = client;
this.s = s;
}

@Override
public Void call() throws Exception
{
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String fromClient;
while ((fromClient = in.readLine()) != null)
{
System.out.println("FROM CLIENT#" + client + ": " + fromClient);
}
in.close();
s.close();
return null;
}
}

输出

FROM CLIENT#0: Hi, I'm John!
FROM CLIENT#2: Hi, I'm Sam!
FROM CLIENT#1: Hi, I'm Ben!
FROM CLIENT#3: Hi, I'm Anne!
FROM CLIENT#4: Hi, I'm Anton!

关于java - 如何处理客户端/服务器应用程序以发送消息和/或文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18637322/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com