1

我开发了一个运行良好的多线程服务器!但现在我想让它第一次发送客户端连接一个字符串,然后继续以相同的常规过程接收字符串并发送文件!这是我的服务器代码

import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.util.Scanner;

class TCPServer {
    public static void main(String argv[]) throws Exception {

        System.out.println("Welcome to the stream Server");
System.out.println("listening to Clients");
        ServerSocket welcomeSocket = new ServerSocket(3248);
        while (true) {
            Socket connectionSocket = welcomeSocket.accept();
            if (connectionSocket != null) {
                Client client = new Client(connectionSocket);
                client.start();

            }
        }
    }
}

class Client extends Thread {
    private Socket connectionSocket;


    public Client(Socket c) throws IOException {
        connectionSocket = c;
    }

    public void run() {

        String path = "C:/pao/new2/";

        File folder = new File(path);
        File[] listOfFiles = folder.listFiles();


        try {

            String fileToSendStr = readFile();
            File fileToSend = null;
            for (File f : listOfFiles)

            {

                if (f.getName().equals(fileToSendStr)) {
                    fileToSend = f;
                    break;
                }
            }
            System.out.println("Connecting to Client to recieve the part " +fileToSendStr);
            if (fileToSend == null) {

            }
            System.out.println("Sending the chunk to Client");
            long length = fileToSend.length();
            byte [] longBytes = new byte[8];
            ByteBuffer bbuffer = ByteBuffer.wrap(longBytes);
            bbuffer.putLong(length);
            connectionSocket.getOutputStream().write(longBytes);

            BufferedOutputStream bout = new BufferedOutputStream(connectionSocket.getOutputStream());
            BufferedInputStream bain = new BufferedInputStream(new FileInputStream(fileToSend));

            byte buffer [] = new byte [1024];
            int i = 0;
            while((i = bain.read(buffer, 0, 1024)) >= 0){
                bout.write(buffer, 0, i);

            }
            System.out.println("chunk sended");
            bout.close();
            bain.close();


        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private String readFile() throws IOException {

        BufferedReader r = new BufferedReader(new InputStreamReader(
                connectionSocket.getInputStream()));
        return r.readLine();

    }
}

想要建立连接的客户端部分不同于它建立该连接的部分。只想第一次检索一个字符串,然后该部分不再可用!

4

2 回答 2

0

ServerSocket.accept()是一种阻塞方法。如果未建立连接或发生超时(先前设置),它将不会返回。

将服务器代码放在客户端实例化的单独线程中,或为套接字设置超时:

ServerSocket welcomeSocket = new ServerSocket(3248);
welcomeSocket.setSoTimeout(2000); // waits 2 seconds for a client.
while (true) {
    (new Thread(new Runnable() {
         public void run() {
            Socket connectionSocket = welcomeSocket.accept();
            if (connectionSocket != null) {
                Client client = new Client(connectionSocket);
                client.start();
            }
          }
      })).start();
      try {
          welcomeSocket.accept();
      } catch(Exception e) {
          //socket timeout.
      }
}
于 2013-04-17T18:57:11.310 回答
0

我不确定我是否理解得很好,但你说目前服务器运行良好,可以为客户服务。你想知道一个客户端之前是否已经连接过?您的服务器和客户端之间的通信跨越多个连接?

这需要概念性的思考。如果您在 HTTP 领域,这将意味着某种会话和/或 cookie 概念。使用 cookie,服务器可以在客户端存储信息(客户端上次连接时,某种状态)。使用会话 ID,您可以在与客户端通信期间跟踪您处于什么状态。

在您的情况下,您可能需要开发一个非常简单的应用程序级协议(ISO/OSI 网络堆栈的顶部)。因此,例如在连接建立后,客户端将向服务器发送一个字节,告知信息交换的位置,然后服务器将根据该信息做出反应。在通信结束时,该“状态”参数将被更新、修改。

这有帮助吗?

于 2013-04-17T19:08:24.370 回答