在读取期间通过套接字连接超时获取请求

时间:2015-02-23 01:45:10

标签: c sockets http ocaml unix-socket

我正在尝试在OCaml中编写一个http客户端:

module Connection = struct
    let sock_fd =
        let s_fd = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
        Unix.setsockopt s_fd Unix.TCP_NODELAY true;
        s_fd

    let read_from_sock () =
        let buffer = Bytes.create 512 in
        let rec read_all request buffer =
            let r = Unix.read sock_fd buffer 0 512 in
            if r < 512 then request ^ buffer
            else read_all (request ^ buffer) buffer in
        read_all "" buffer

    let write_to_sock str =
        let len = String.length str in
        let _ = Unix.write sock_fd str 0 len in ()

    let make_request request serv_addr =
        Unix.connect sock_fd serv_addr;
        write_to_sock request

    class connection address port =
        object
            val serv_addr = Unix.ADDR_INET (Unix.inet_addr_of_string address, port)

            method get_response request =
                let _ = make_request request serv_addr in
                let rec wait_for_response () =
                    let response = read_from_sock () in
                    match String.length response with
                    | 0 -> wait_for_response ()
                    | _ -> Printf.printf "%s\n" response in
                wait_for_response ();
                Unix.shutdown sock_fd Unix.SHUTDOWN_ALL;
                Unix.close sock_fd
        end

    let create address port = new connection address port
end

let connection = Connection.create "54.175.219.8" 80;;
connection#get_response "GET / HTTP/1.1\r\n"

程序只会挂起,直到在读取过程中重置连接时崩溃。时髦的部分是,没有其他错误被抛出。由于OCaml没有返回像C这样的int响应,所以我假设我连接或创建了一个错误的连接或创建了运行时会引发错误的套接字。

如果您不熟悉OCaml,我会假设(非常粗略)伪C等效于我正在做的事情(也许这有助于调试):

int sock_fd = socket(PF_INET, SOCK_STREAM);
setsockopt(sock_fd, TCP_NODELAY, 1);

serv_addr addr {"54.175.219.8", 80};
connect(sock_fd, &serv_addr);
write(sock_fd, "GET / HTTP/1.1\r\n");

char buffer[512];
while (buffer = read(sock_fd)) {
    printf("%s\n", buffer);
}

shutdown(sock_fd, SHUTDOWN_ALL);
close(sock_fd);

如果没用,请忽略它。我想我会用伪代码总结一下。有什么明显的问题吗? (除了不读取C中socket / connect / write的int响应,因为OCaml的运行时应该?在这里处理错误。)

1 个答案:

答案 0 :(得分:2)

HTTP协议中,请求最终应该有两个空行,而不是一行(用外行术语表示)。在您的情况下,服务器只是等待第二个&#34;输入&#34;,并且您的客户端阻塞,直到它收到响应。只需在您的请求中添加额外的\r\n,一切都会有效......更好。至少你会收到回复。但是你的代码包含一些故障,所以期望出现问题。

仅为了您的信息,在OCaml中有很多很好的网络库。我认为最好的是cohttp。此外,您可能会发现有趣的我的socket library,比cohttp

更低级别。
相关问题