我可以将数据发送到sinatra服务器(字符串),但我不确定如何在sinatra代码中实际接收数据。有人能帮忙吗?
Java客户端(我用来发送数据)代码:
private static void contactServer() {
try {
String text = "This is a text please work";
Socket sock = new Socket("localhost", 4567);
OutputStream os = sock.getOutputStream();
URL url = new URL("http://localhost:4567/hello");
PrintWriter writer = new PrintWriter(os);
writer.flush();
writer.write(text);
url.openStream();
System.out.println("done");
String strTemp = "";
/*while(null != (strTemp = br.readLine())){
System.out.println(strTemp);
}*/
} catch (Exception e) {
e.printStackTrace();
}
}
这行不通。Sinatra的服务器理解并使用一种名为的语言http协议,因此发送字符串:
"This is a text please work"
通过插座连接到Sinatra应用程序是一种绝望的祈祷。
协议是一组规则,指定客户端和服务器如何相互通信,然后双方都可以准确地理解对方在说什么。对于http协议,客户端发送称为a request
的内容,服务器使用称为a response
的内容进行回复。请求和响应必须严格按照http协议指定的规则进行格式化。请求的血腥细节如下:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
因此,您的java程序需要将a request
发送到Sinatra的服务器,这只是一个以精确方式格式化的字符串。下面是一个简单的GET请求的样子:
GET /path/to/page HTTP/1.1
Host: localhost:4567
如果您想对页面进行GET请求:
http://localhost:4567/page1
(即击中Sinatra路线get '/page1'
)
则该页面的一个简单GET请求将如下所示:
GET /page1 HTTP/1.1
Host: localhost:4567
此外,无论使用何种操作系统,http请求中的每一行都必须以"\r\n"结尾。这两个字符是http协议的一部分。此外,在最后一个标头之后,必须有一个空行,由另一个"\r\n"表示,如下所示:
GET /page1 HTTP/1.1rnHost: localhost:4567rnrn
这是java:
import java.io.*;
import java.net.*;
public class Sinatra {
private static void contactServer() {
try {
Socket sock = new Socket("localhost", 4567);
OutputStream os = sock.getOutputStream();
PrintWriter writer = new PrintWriter(os);
String[] text = {
"GET /page1 HTTP/1.1",
"Host: localhost:4567",
};
String request = "";
for(int i=0; i < text.length; ++i) {
request += text[i] + "rn";
}
request += "rn";
System.out.println(request);
writer.write(request);
writer.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Sinatra.contactServer();
}
}
注意:在我运行该java程序的前几次,服务器(我用$ ruby myapp.rb
启动)抛出了以下错误:
[2013-08-19 20:10:11] ERROR Errno::ECONNRESET: Connection reset by peer
/Users/7stud/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpserver.rb:80:in `eof?'
/Users/7stud/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpserver.rb:80:in `run'
/Users/7stud/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
但是,当我再运行几次java程序时,服务器最终表现良好。我不知道是什么导致了那个错误。当我在FireFox中输入url时,服务器从未出现过错误。因此,我使用Firebug查看Firefox发送的请求;然后我在java程序中使用了所有相同的请求头,但服务器仍然抛出了那个错误。
编辑:我可以在关闭套接字之前让java程序休眠1秒,从而消除服务器错误。当显式关闭套接字或程序结束时,套接字将关闭。如果没有睡眠,我认为套接字会在服务器仍在处理请求时关闭。因为浏览器保持套接字打开,所以浏览器永远不会导致服务器抛出该错误。
ruby客户端也会出现相同的服务器错误:
require 'socket'
port = 4567
host = 'localhost'
s = TCPSocket.new host, port
req = [
"GET /page1 HTTP/1.1",
"Host: localhost:4567",
"Accept: */*",
]
req = req.join("rn") << ("rn" * 2)
print req
s.write req
s.flush
#sleep(1)
s.close
解决方法也是一样的。唯一琐碎的细节是为什么curl
unix命令没有导致服务器抛出错误:
$ curl -v http://localhost:4567/page1
* About to connect() to localhost port 4567 (#0)
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 4567 (#0)
> GET /page1 HTTP/1.1
> User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8r zlib/1.2.3
> Host: localhost:4567
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 0
< X-Xss-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20)
< Date: Tue, 20 Aug 2013 04:59:16 GMT
< Connection: Keep-Alive
<
* Connection #0 to host localhost left intact
* Closing connection #0
使用-v选项,curl打印出请求和响应。使用curl发出请求,我从未见过服务器抛出那个错误。我想知道卷曲是否也能睡觉?