【问题标题】:Java chat program which also sends file也发送文件的 Java 聊天程序
【发布时间】:2016-04-08 13:48:53
【问题描述】:

我制作了一个基本的聊天程序,它也可以发送,但它不完整。一切运行良好,除了当我发送一个文件时,我的程序接收它没有任何问题,但它给出了一个套接字关闭错误。

客户

import java.net.*;
import java.io.*;

public class chatClnt {

    public static int PORT = 6666;
    public static String IP_ADDR = "192.168.15.1";
    public static String F = "FILE MODE";

    public static void main(String[] ar) {

        try {
            InetAddress ipAddress = InetAddress.getByName(IP_ADDR);

            System.out.println("\nconnecting......");
            Socket socket = new Socket(ipAddress, PORT);
            System.out.println("\nconnected");

            InputStream sin = socket.getInputStream();
            OutputStream sout = socket.getOutputStream();

            DataInputStream in = new DataInputStream(sin);
            DataOutputStream out = new DataOutputStream(sout);

            BufferedReader keyboard = new BufferedReader(new         InputStreamReader(System.in));

            String line = null;
            String fname = null;

            while (true) {
                System.out.println("\nYou(Plain Text):>");
                line = keyboard.readLine();
                out.writeUTF(line);
                out.flush();
                if (line.equals(F)) {
                    //Sending File
                    OutputStream fout = socket.getOutputStream();
                    FileInputStream fis = null;
                    BufferedInputStream bis = null;
                    try {
                        System.out.println("Enter the path: ");
                        fname = keyboard.readLine();
                        File myFile = new File(fname);
                        byte[] mybytearray = new byte[(int)myFile.length()];
                        fis = new FileInputStream(myFile);
                        bis = new BufferedInputStream(fis);
                        bis.read(mybytearray,0,mybytearray.length);

                        fout = socket.getOutputStream();
                        System.out.println("Sending " + fname + "(" + mybytearray.length + " bytes)");
                        fout.write(mybytearray,0,mybytearray.length);
                        fout.flush();
                        System.out.println("Done.");
                    } finally {
                        if (bis != null) bis.close();
                        if (fout != null) fout.close();
                    }


                    line = in.readUTF(); // wait for the server to send a line of text.
                    System.out.println("\nSender(Plain Text):> " + line);
                    System.out.println();
                }
            }
        } catch(Exception x) {
            x.printStackTrace();
        }
    }
}

服务器

import java.net.*;
import java.io.*;


public class chatSrv {

    public static int PORT = 6666;
    public static String F = "FILE MODE";
    public final static String FILE_TO_RECEIVE = "received.txt";
    public final static int FILE_SIZE = 999999999;

    public static void main(String[] ar) {

        try { 
            ServerSocket ss = new ServerSocket(PORT);
            System.out.println("\nconnecting...");
            Socket socket = ss.accept();

            System.out.println("\nconnected");
            System.out.println();

            InputStream sin = socket.getInputStream();
            OutputStream sout = socket.getOutputStream();

            DataInputStream in = new DataInputStream(sin);
            DataOutputStream out = new DataOutputStream(sout);

            String line = null;
            int bytesRead;
            int current = 0;

            while (true) {
                line = in.readUTF();

                //Receiving File
                if (line.equals(F)) {
                    FileOutputStream fos = null;
                    BufferedOutputStream bos = null;
                    try {
                        byte [] mybytearray = new byte [FILE_SIZE];
                        fos = new FileOutputStream(FILE_TO_RECEIVE);
                        bos = new BufferedOutputStream(fos);
                        bytesRead = sin.read(mybytearray,0,mybytearray.length);
                        current = bytesRead;

                        do {
                            bytesRead = sin.read(mybytearray, current, (mybytearray.length-current));
                            if (bytesRead >= 0) current += bytesRead;
                        } while (bytesRead > -1);

                        bos.write(mybytearray, 0 , current);
                        bos.flush();
                        System.out.println("File " + FILE_TO_RECEIVE+ " downloaded (" + current + " bytes read)");
                    } finally {
                        if (fos != null) fos.close();
                        if (bos != null) bos.close();
                    }

                    System.out.println("\nSender(Plain Text):> " + line);
                    BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));

                    System.out.println("\nYou(Plain Text):>");
                    line = keyboard.readLine();
                    out.writeUTF(line); 
                    out.flush(); 
                    System.out.println();
                }
            }
        } catch(Exception x) {
            x.printStackTrace();
        }
    }
}

【问题讨论】:

  • 能否请您发布实际错误?还有次要的编码风格注意,当你导入时尝试导入特定的包而不是import java.net.*。这是一个好习惯。
  • remove fout.close();,您将永远运行 while 循环并在接收到 hte 文件一次后关闭,这意味着在单个文件后关闭流,因此它将无法读取更多数据从那个流
  • 在删除 f.out.close() 时将挂起程序,因为文件永远不会关闭

标签: java file sockets chat transfer


【解决方案1】:

当您关闭套接字的输出流时,这也会关闭套接字。 documentation 说:

关闭返回的OutputStream 将关闭关联的套接字。

所以你不能关闭流。但是如果你不关闭它,你永远不会在接收方得到-1

因此,基本上,您不能使用从磁盘读取文件时使用的相同读取过程。您需要设计一个协议,允许您在保持流打开的同时读取文件。可能的策略:

  • 为此打开第二个套接字。例如,在可用端口上打开一个套接字,并向服务器发送一条消息,告诉服务器它应该使用该端口号连接到另一个套接字。然后你可以通过另一个套接字发送整个文件并关闭它。或者要求服务器打开第二个套接字并告诉您要连接到哪个端口号。这是 ftp 协议使用的策略。
  • 提前以字节为单位发送文件的长度,然后在接收端读取那么多字节。这是 HTTP 使用的策略,例如,当它发送 Content-length: 标头时。

请记住,文件可能很长,因此如果您决定发送长度,请使用long 而不是int

【讨论】:

  • 请帮助我更准确一点
  • 如果我不关闭OutputStream程序不前进,我该怎么办
  • @SiddharthMazumdar 正如我所说,你不能只是决定不关闭它——因为你永远不会在另一端得到 -1,它只会等待更多输入。相反,您应该根据其中一种策略重新考虑您的协议。
猜你喜欢
  • 1970-01-01
  • 2014-01-31
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多