通过套接字连接到第二台服务器 API
Connect to second server API trough sockets
我正在 Python 中编写一个项目,它将有两个不同的(独立的)应用程序。
- 代理(普通Python代码,无框架)
- API到send/receiveJSON的数据库(用tornado 4.4框架写的)
我的项目将做这样的事情:
- 在数据库应用程序中,您可以添加过滤器:1 - 要过滤掉网页的锚标记,2 - URL 要赋予 403 状态的模式。
- 特定 URL (api/send-to-world/filter_type/) 上的数据库应用程序为 JSON 提供 filter_type = filter_type 的所有过滤器(来自以上)
- 在访问网页时,代理首先通过在上面的 URL 上捕获一个 JSON 来获取过滤器,然后进行过滤
- 为了统计,过滤后的内容被发送到数据库API接收到一个JSON(url:/api/receive-from-world/)并将内容保存到数据库.
为了测试项目,我将应用程序放在我的本地主机上:
- 端口 8000 上的代理服务器
- 900 端口上的数据库应用程序
由于 Tornado 框架编写了两个应用程序,该项目运行良好,但出于个人原因,我想让 PROXY 更底层 -> 使用套接字。
为此,我将 Proxy 应用程序重新编写为纯 Python 代码,但我遇到了一个小问题。问题是,当我创建一个套接字并且我想从数据库 API 接收一个 JSON 时,数据库应用程序给我一个 404 错误(而如果我在数据库上访问 URL它工作正常)。我不知道可能是什么问题。
我的代理 class 使用 send_json 和套接字创建方法:
class Proxy(object):
u"""The PROXY class."""
(...)
def get_remote_response(self, host, port, data):
u"""Method that creates a socket to the remote_address and gets the response.
:param host: remote_host,
:param port: remote_port,
:param data: data to send.
:return response: the response without the headers.
"""
response_text = ''
try:
remote_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Trying to connect to:%s : %s \n\n" % (host, port)
remote_sock.connect((host, port))
remote_sock.send(data)
remote_sock.settimeout(0.5)
while True:
try:
response = remote_sock.recv(self.buffor_size)
if len(response) == 0:
break
except socket.error:
break
response_text += response
except socket.error, msg:
print str(msg)
remote_sock.close()
response = response_text[response_text.index('\r\n\r\n') + 1:]
return response
def get_filters(self, filter_id, **kwargs):
u"""Method that gets a JSON with filters from the remote server
:param filter_id: filter id.
:return filters: list of filters from the remote server.
"""
filters = list()
remote_host = '127.0.0.1'
remote_port = 9000
request_url = 'http://%s:%s/api/send-to-world/%s/' % (remote_host, str(remote_port), filter_id)
first_line_of_request = 'GET ' + request_url + ' HTTP/1.1\r\n'
headers = {
'Host': remote_host,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
request = first_line_of_request
for header in headers:
request += '%s: %s\r\n' % (header, headers[header])
request += '\r\n'
print "request:\n", request
response = self.get_remote_response(remote_host, remote_port, request)
print "response:\n", response
if response:
data = None
try:
my_json = response
data = json.loads(my_json.decode('utf-8'))
except ValueError:
message = 'Cannot parse JSON.'
# self.send_error(400, message=message)
filters = []
for one_filter in data:
filters.append((one_filter.get('filter_id'), one_filter.get('filter_name')))
return filters
PROXY上的绑定、监听、接受已经完成,我想这里就不用上传了。如果是这样,就这么说:)
我留下了打印件,以便您可以查看数据库应用程序中的内容:
要求:
request:
GET http://127.0.0.1:9000/api/send-to-world/2/ HTTP/1.1
Host: 127.0.0.1
Content-Type: application/json
Accept: application/json
响应:
Trying to connect to:127.0.0.1 : 9000
response:
Traceback (most recent call last):
File "/home/dave/.virtualenvs/teleV1/local/lib/python2.7/site-packages/tornado/web.py", line 1446, in _execute
result = self.prepare()
File "/home/dave/.virtualenvs/teleV1/local/lib/python2.7/site-packages/tornado/web.py", line 2174, in prepare
raise HTTPError(self._status_code)
HTTPError: HTTP 404: Not Found
尝试获取过滤器时来自数据库应用程序的日志:
tornado working on port 9000
WARNING:tornado.access:404 GET http://127.0.0.1:9000/api/send-to-world/2/ (127.0.0.1) 2.75ms
当我通过网络浏览器访问它时,它给了我 JSON。
总结一下:如何使用套接字连接从我的数据库应用程序接收 JSON?我认为如果服务器在不同的端口上工作,那么问题不应该出在 host: 127.0.0.1
上。如果我错了,我不能在一台计算机上做这样的事情,那么请纠正我:)
我怀疑这是问题所在,但你说你的数据库应用程序在端口 900 上侦听,但你的代理正在连接到端口 9000...
不要在 HTTP 请求中包含协议、主机名和端口 headers,因此更改
request_url = 'http://%s:%s/api/send-to-world/%s/' % (remote_host, str(remote_port), filter_id)
至
request_url = '/api/send-to-world/%s/' %filter_id
例如,让您的代理从 whosebug.com 获取这篇文章:
remote_host = 'whosebug.com'
remote_port = 80
request_url = 'posts/43481916'
first_line_of_request = 'GET ' + request_url + ' HTTP/1.1\r\n'
headers = {
'Host': remote_host,
'Content-Type': 'text/html',
'Accept': 'text/html'
}
request = first_line_of_request
for header in headers:
request += '%s: %s\r\n' % (header, headers[header])
request += '\r\n'
response = self.get_remote_response(remote_host, remote_port, request)
我正在 Python 中编写一个项目,它将有两个不同的(独立的)应用程序。
- 代理(普通Python代码,无框架)
- API到send/receiveJSON的数据库(用tornado 4.4框架写的)
我的项目将做这样的事情:
- 在数据库应用程序中,您可以添加过滤器:1 - 要过滤掉网页的锚标记,2 - URL 要赋予 403 状态的模式。
- 特定 URL (api/send-to-world/filter_type/) 上的数据库应用程序为 JSON 提供 filter_type = filter_type 的所有过滤器(来自以上)
- 在访问网页时,代理首先通过在上面的 URL 上捕获一个 JSON 来获取过滤器,然后进行过滤
- 为了统计,过滤后的内容被发送到数据库API接收到一个JSON(url:/api/receive-from-world/)并将内容保存到数据库.
为了测试项目,我将应用程序放在我的本地主机上:
- 端口 8000 上的代理服务器
- 900 端口上的数据库应用程序
由于 Tornado 框架编写了两个应用程序,该项目运行良好,但出于个人原因,我想让 PROXY 更底层 -> 使用套接字。
为此,我将 Proxy 应用程序重新编写为纯 Python 代码,但我遇到了一个小问题。问题是,当我创建一个套接字并且我想从数据库 API 接收一个 JSON 时,数据库应用程序给我一个 404 错误(而如果我在数据库上访问 URL它工作正常)。我不知道可能是什么问题。
我的代理 class 使用 send_json 和套接字创建方法:
class Proxy(object):
u"""The PROXY class."""
(...)
def get_remote_response(self, host, port, data):
u"""Method that creates a socket to the remote_address and gets the response.
:param host: remote_host,
:param port: remote_port,
:param data: data to send.
:return response: the response without the headers.
"""
response_text = ''
try:
remote_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Trying to connect to:%s : %s \n\n" % (host, port)
remote_sock.connect((host, port))
remote_sock.send(data)
remote_sock.settimeout(0.5)
while True:
try:
response = remote_sock.recv(self.buffor_size)
if len(response) == 0:
break
except socket.error:
break
response_text += response
except socket.error, msg:
print str(msg)
remote_sock.close()
response = response_text[response_text.index('\r\n\r\n') + 1:]
return response
def get_filters(self, filter_id, **kwargs):
u"""Method that gets a JSON with filters from the remote server
:param filter_id: filter id.
:return filters: list of filters from the remote server.
"""
filters = list()
remote_host = '127.0.0.1'
remote_port = 9000
request_url = 'http://%s:%s/api/send-to-world/%s/' % (remote_host, str(remote_port), filter_id)
first_line_of_request = 'GET ' + request_url + ' HTTP/1.1\r\n'
headers = {
'Host': remote_host,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
request = first_line_of_request
for header in headers:
request += '%s: %s\r\n' % (header, headers[header])
request += '\r\n'
print "request:\n", request
response = self.get_remote_response(remote_host, remote_port, request)
print "response:\n", response
if response:
data = None
try:
my_json = response
data = json.loads(my_json.decode('utf-8'))
except ValueError:
message = 'Cannot parse JSON.'
# self.send_error(400, message=message)
filters = []
for one_filter in data:
filters.append((one_filter.get('filter_id'), one_filter.get('filter_name')))
return filters
PROXY上的绑定、监听、接受已经完成,我想这里就不用上传了。如果是这样,就这么说:)
我留下了打印件,以便您可以查看数据库应用程序中的内容:
要求:
request: GET http://127.0.0.1:9000/api/send-to-world/2/ HTTP/1.1 Host: 127.0.0.1 Content-Type: application/json Accept: application/json
响应:
Trying to connect to:127.0.0.1 : 9000 response: Traceback (most recent call last): File "/home/dave/.virtualenvs/teleV1/local/lib/python2.7/site-packages/tornado/web.py", line 1446, in _execute result = self.prepare() File "/home/dave/.virtualenvs/teleV1/local/lib/python2.7/site-packages/tornado/web.py", line 2174, in prepare raise HTTPError(self._status_code) HTTPError: HTTP 404: Not Found
尝试获取过滤器时来自数据库应用程序的日志:
tornado working on port 9000 WARNING:tornado.access:404 GET http://127.0.0.1:9000/api/send-to-world/2/ (127.0.0.1) 2.75ms
当我通过网络浏览器访问它时,它给了我 JSON。
总结一下:如何使用套接字连接从我的数据库应用程序接收 JSON?我认为如果服务器在不同的端口上工作,那么问题不应该出在 host: 127.0.0.1
上。如果我错了,我不能在一台计算机上做这样的事情,那么请纠正我:)
我怀疑这是问题所在,但你说你的数据库应用程序在端口 900 上侦听,但你的代理正在连接到端口 9000...
不要在 HTTP 请求中包含协议、主机名和端口 headers,因此更改
request_url = 'http://%s:%s/api/send-to-world/%s/' % (remote_host, str(remote_port), filter_id)
至
request_url = '/api/send-to-world/%s/' %filter_id
例如,让您的代理从 whosebug.com 获取这篇文章:
remote_host = 'whosebug.com'
remote_port = 80
request_url = 'posts/43481916'
first_line_of_request = 'GET ' + request_url + ' HTTP/1.1\r\n'
headers = {
'Host': remote_host,
'Content-Type': 'text/html',
'Accept': 'text/html'
}
request = first_line_of_request
for header in headers:
request += '%s: %s\r\n' % (header, headers[header])
request += '\r\n'
response = self.get_remote_response(remote_host, remote_port, request)