如何在Delphi客户端接收Java服务器返回的HTTP响应内容?
解决Delphi客户端无法接收Java服务器响应的问题
看起来你的问题出在两个核心点:Java服务器端的请求读取逻辑有漏洞,以及Delphi客户端读取响应的方式不正确。让我一步步帮你修复:
一、修复Java服务器的请求读取逻辑
你当前用inputStream.available() > 0判断是否继续读取请求,这是不可靠的——available()只返回当前输入缓冲区中可立即读取的字节数,客户端可能还在发送数据,服务器就提前退出循环了。这会导致服务器没有完整处理客户端的HTTP请求,进而让连接处于异常状态,客户端无法正确接收响应。
把服务器的读取代码改成这样,按照HTTP协议的方式完整读取请求:
ServerSocket s = new ServerSocket(8080); Socket accept = s.accept(); InputStream inputStream = accept.getInputStream(); // 用BufferedReader按行读取HTTP请求头 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { System.out.println(line); // 遇到空行表示请求头结束 if (line.isEmpty()) { break; } } // 读取请求体(如果有的话) char[] buffer = new char[1024]; int len; while ((len = reader.read(buffer)) != -1) { System.out.print(new String(buffer, 0, len)); } System.out.println("finish recieve"); System.out.println("start write"); OutputStream outputStream = accept.getOutputStream(); // 补充Content-Length头,让客户端明确响应体长度 outputStream.write("HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\nasdf".getBytes()); System.out.println("data sent to client"); outputStream.flush(); // 先关闭输出流确保数据全部发送,再关闭Socket outputStream.close(); accept.close(); s.close(); // 别忘了关闭ServerSocket释放端口
二、修复Delphi客户端的响应读取逻辑
你的客户端代码误用了InternetGetLastResponseInfo——这个函数是用来获取错误场景下的响应信息,不是读取正常的服务器响应内容。正确的做法是用InternetReadFile循环读取响应数据,同时可以先用HttpQueryInfo获取响应状态码等关键信息。
修改后的Delphi代码如下:
// 发送请求体之后 ShowMessage('Wait for server to send data'); var statusCode: DWORD; statusCodeLen: DWORD; buffer: array[0..1023] of Char; bytesRead: DWORD; response: string; begin // 获取响应状态码 statusCodeLen := SizeOf(statusCode); if not HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE or HTTP_QUERY_FLAG_NUMBER, @statusCode, statusCodeLen, nil) then begin ShowMessage('Failed to get status code: ' + IntToStr(GetLastError)); Exit; end; ShowMessage('Server status code: ' + IntToStr(statusCode)); // 循环读取响应内容 response := ''; while InternetReadFile(hRequest, @buffer, SizeOf(buffer) - 1, bytesRead) do begin if bytesRead = 0 then Break; // 读取完成 buffer[bytesRead] := #0; // 确保字符串终止 response := response + buffer; end; if GetLastError <> ERROR_SUCCESS then ShowMessage('Failed to read response: ' + IntToStr(GetLastError)) else begin ShowMessage('Response content: ' + response); ShowMessage('Response size: ' + IntToStr(Length(response))); end; // 结束请求并关闭句柄 if not HttpEndRequest(hRequest, nil, 0, 0) then ShowMessage('Failed to end request: ' + IntToStr(GetLastError)); InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hConn); end;
三、额外注意事项
- 确保Delphi代码中已经正确调用了
HttpSendRequest发送请求头(InternetWriteFile仅用于发送请求体,请求头需要先通过HttpSendRequest发送)。 - Java服务器处理完请求后,务必关闭
ServerSocket,避免端口被长期占用。
按照上面的修改,客户端应该就能正确接收到服务器返回的asdf内容了。
内容的提问来源于stack exchange,提问作者Grim
相关产品推荐
相关产品推荐

