如何在java中通过套接字发送EOF

时间:2016-08-04 19:47:36

标签: java html sockets

基本上是一个从服务器请求图像的html文件,我创建了一个执行响应的服务器,但是当对图像的html请求时,服务器完全发送图像,但客户端浏览器保持在加载图像并说'#34;从服务器转移数据",我在互联网上进行了我的研究,我发现只需关闭连接即可完成,但它对我没有用。

这是我在java中构建服务器的代码:

package lesson1;

import java.io.*;
import java.net.*;
import java.lang.Exception;

public class SecClass{

BufferedReader fd;
String  link = null, HTMLData = null, WEBROOT = "D:/PDT1";
String ptr = null, directory = null,
        GET_HEAD_POST = null, Protocol = null;
ServerSocket SRVSOCK;
Socket SOCK;
DataOutputStream dOut;
DataInputStream dInput;
InputStreamReader IR;


public static void main(String[] args) throws Exception
{
    SecClass SERVER = new SecClass();
    SERVER.run();
}

public void run() throws Exception
{
    SRVSOCK = new ServerSocket(80);
    while(true){
        SOCK = SRVSOCK.accept();
        new Thread(new SocketThread(SOCK)).start();
    }
}

public class SocketThread implements Runnable {

    @SuppressWarnings("unused")
    private Socket socket;

    public SocketThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try{
            dOut = new DataOutputStream(SOCK.getOutputStream());
        }catch(Exception ie){
            System.out.println("Cound'nt create dOut");
        }

        try{
            IR = new InputStreamReader(SOCK.getInputStream());
        }catch(Exception ie){
            System.out.println("Cound'nt create IR");
        }


        BufferedReader BR = new BufferedReader(IR);
        String MESSAGE = null;
        System.out.println("Received Request!");
        try{
            MESSAGE = BR.readLine();

        }catch(Exception ie){
            System.out.println("Cound'nt Receive Message");
        }
        System.out.println(MESSAGE);

        if(MESSAGE != null && MESSAGE.contains("HTTP/")){
            Protocol = MESSAGE.substring(MESSAGE.length()-8);
            System.out.println("Request protocol is " + Protocol);
        } else {
            System.out.println("It's a Not HTTP request");
        }

        if(MESSAGE != null && MESSAGE.contains("GET ")){
            GET_HEAD_POST = "GET ";
            System.out.println("Reqest is GET");
            ptr = MESSAGE.substring(4);
            directory = ptr.substring(0,ptr.length()-9);
            link = ptr.substring(ptr.length() - 10);
            System.out.println(link);

        } else if(MESSAGE != null && MESSAGE.contains("HEAD ")){
            System.out.println("Request is HEAD");
            GET_HEAD_POST = "HEAD ";
            ptr = MESSAGE.substring(5);
            directory = ptr.substring(0,ptr.length()-9);
            link = ptr.substring(ptr.length() - 10);
        } else if(MESSAGE != null && MESSAGE.contains("POST ")){
            System.out.println("Request is POST");

        } else {
            System.out.println("Cound'nt verify request");
            try{
                SRVSOCK.close();
            }catch(Exception ie){
                System.out.println("Could not close SRVSOCK");
            }
            try{
                SOCK.close();
            }catch(Exception ie){
                System.out.println("Could not close SOCK");
            }

        }

        if(MESSAGE == null)
        {
            System.out.println("Unknown request");
            try{
                SOCK.close();
            }catch(Exception ie){
                System.out.println("Could not close SOCK");
            }

        } else {
            if((link.charAt(0)) == '/' && link != null){
                link = WEBROOT + directory + "index.html";
                try{

                    OpenFile();
                    dOut.close();
                    SOCK.close();
                    System.out.println("Came out of Openfile Func");

                }catch(Exception ie){
                    System.out.println("Could not Call for OpenFile Function");
                }
                try{
                    MESSAGE = BR.readLine();
                }catch(Exception ie){
                    System.out.println("Could not Receive message");
                }

                System.out.println(MESSAGE);

            } else {
                System.out.println("User Requested for a file");
                System.out.println(directory);

                link = WEBROOT + directory;
                try{
                    OpenFile();
                    dOut.close();
                    SOCK.close();
                }catch(Exception ie){
                    System.out.println("Could not Call for OpenFile Function");
                }
            }

        }
    }
}
public void OpenFile() throws Exception{
    try (BufferedReader br = new BufferedReader(new FileReader(link))) {
        String line;
        System.out.println("Request Link is: " + link);
        while ((line = br.readLine()) != null) {
            System.out.println(line);
            dOut.writeBytes(line);
        }
        dOut.flush();
        dOut.close();
        SOCK.close();
    } catch(Exception e){
        System.out.println(link);
        dOut.writeBytes("<html><h1>404 File Not Found</h1></html>");
        System.out.println("File Does not Exist");

    }
}
}

这是我的HTML代码:

<html>
<head>
    <meta charset="utf-8"/>
    <title>hello</title>
</head>
<body>
    <header> 
        <div class="HeaderBox">
            <img src="logo.png" alt="image" class="logoBox"/>
        </div>
    </header>
</body>
</html>

正如您所看到的那样,当图像完全传输时,我已经尝试了两次关闭服务器上的连接,但是在我的浏览器中它停留在加载中,而在底部它表示从127.0.0.1传输数据

1 个答案:

答案 0 :(得分:1)

首先移动除ServerSocket SRVSOCK之外的所有字段;从类SecClass到类SocketThread。制作套接字SOCK; run()方法中的本地引用。您的代码的原因是使用多线程。因此将它们移动到SocketThread类。同时移动OpenFile()以获得更清晰的方法。

您对不同的线程请求使用相同的SOCK引用。关闭时,请参考SOCK字段。这是导致错误行为的原因。什么可能并且最常发生的是一个线程因为不正确的SOCK引用而关闭另一个线程的套接字。

您需要做的是:

public void run() throws Exception
{
SRVSOCK = new ServerSocket(8088);
while(true){
    Socket SOCK;
    SOCK = SRVSOCK.accept();
    new Thread(new SocketThread(SOCK)).start();
}
} 

在SocketThread中不使用SOCK引用。 例如。   SOCK.getInputStream()。更改为使用SocketThread字段的socket.getInputStream()。同样改变其他人。

至于为什么图像没有渲染: 将OpenFile()更改为:

public void OpenFile() throws Exception{
    try (FileInputStream br = new FileInputStream (link)) {
        System.out.println("Request Link is: " + link);
        int i;
        while ((i = br.read()) > -1)
            dOut.write(i);

           dOut.flush();
            dOut.close();
            SOCK.close();
        } catch(Exception e){
            System.out.println(link);
            dOut.writeBytes("<html><h1>404 File Not Found</h1></html>");
            System.out.println("File Does not Exist");

        }
}

更改基本上是以字节形式读取文件并将其作为字节写入响应流。在你的情况下发生的事情是你正在读它作为字符串。

您可以查看link使用阅读器与输入流读取文件之间的区别。

适合我。让我知道它是否适合你。