Как вы используете сокет Python с stunnel?

Я пытаюсь реализовать сокет TCP через stunnel, но не знаю, как захватить ответ сервера. Мой файл конфигурации stunnel точно такой:

[Coinbase]
client = yes
accept = 127.0.0.1:4197
connect = fix.gdax.com:4198
verify = 4
CAfile = /etc/fix.gdax.com.pem

И код Python, который у меня есть:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 4197))
msg = b'GET / HTTP/1.1\nHost: www.google.com\n\n' # ping google as a means of testing 
s.send(msg)
print(s.recv(1024))

Какое бы сообщение я ни отправил через сокет (включая те, которые ожидает сервер, расположенный по адресу fix.gdax.com), результатом этого оператора печати всегда будет просто пустая строка в байтовой форме:

b''

Журнал stunnel выглядит следующим образом:

2017.11.02 20:49:58 LOG5[7]: Service [Coinbase] accepted connection from 
127.0.0.1:65205
2017.11.02 20:49:58 LOG5[7]: s_connect: connected 52.86.60.82:4198
2017.11.02 20:49:58 LOG5[7]: Service [Coinbase] connected remote server from 
192.168.0.14:65206
2017.11.02 20:49:58 LOG5[7]: Certificate accepted at depth=0: C=US, 
ST=California, L=San Francisco, O="Coinbase, Inc.", CN=*.gdax.com
2017.11.02 20:50:06 LOG3[7]: readsocket: Connection reset by peer 
(WSAECONNRESET) (10054)
2017.11.02 20:50:06 LOG5[7]: Connection reset: 37 byte(s) sent to TLS, 0 
byte(s) sent to socket

Моя интерпретация этого заключается в том, что сообщение проходит нормально, сертификат действителен и т. д., но я не могу понять, как получить данные, отправленные обратно сервером... очень признательна за любую помощь! Я новичок в TCP и SSL, поэтому прошу прощения, если какая-либо терминология неверна.


person jp94    schedule 02.11.2017    source источник


Ответы (1)


socket.recv() вернет пустую строку, если соединение закрыто удаленной стороной.

Похоже, вы пытаетесь подключиться к шлюзу FIX. Для сервера FIX вполне стандартно закрывать соединение без какого-либо ответа, если он не получает правильное сообщение LOGON. Самое первое сообщение, которое вы отправляете, должно быть LOGON — что-то вроде:

8=FIX.4.4|9=74|35=A|34=1|49=SenderCompIdGoesHere|52=20171103-01:15:00.000|56=TargetCompIdGoesHere|98=0|108=30|10=144

где "|" является символом SOH (ASCII-код 01). Если вы не отправляете это сообщение или в нем что-то не так (например, CompID или версия FIX, отметка времени и т. д.), сервер, как правило, просто закрывает соединение (из-за чего приходится немного гадать, чтобы выяснить, что вы отправляют неправильно).

Кроме того, вы можете отправлять только сообщения протокола FIX, строка "GET ...", с помощью которой вы пытаетесь связаться с Google, является частью протокола HTTP - она ​​не будет распознана сервером FIX.

person xpa1492    schedule 03.11.2017
comment
легенда, спасибо! Я думал, что это будет так. Я попробую сегодня и дам вам знать, как это происходит. - person jp94; 03.11.2017
comment
Я отправляю сообщение об исправлении с | символ, набранный с клавиатуры, однако это не то же самое, что код символа ASCII 0, и я думаю, именно поэтому он все еще не работает - можете ли вы посоветовать, как построить сообщение, чтобы оно было байтовым объектом и имело правильный разделитель между каждое из полей? Ваше здоровье! - person jp94; 04.11.2017