Я пытаюсь создать соединение между сервером Python и клиентом Java (который находится в Android), идея состоит в том, что только клиент отправляет данные на сервер, а сервер будет обрабатывать вещи. однако проблема в том, что при первой отправке сообщения сервер получает сообщение; а затем, когда я пытаюсь отправить следующее сообщение. сервер ничего не получает.
сервер очень простой: вот отрывок:
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
client_socket, client_address = server_socket.accept()
print 'Connect with ' + client_address[0]
while check_if_directx_game():
data = client_socket.recv(1024).decode("UTF-8")
if 'SBA' in data:
PressKey(a)
if "PBA" in data:
ReleaseKey(a)
else:
print data
print "was here"
client_socket.close()
server_socket.close()
на стороне клиента:
public class SendMessage extends AsyncTask<String,Void,Void>{
private Exception exception;
@Override
protected Void doInBackground(String... params){
try {
try {
Socket socket = new Socket("192.168.1.178", 9000);
PrintWriter ToServer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
ToServer.print(params[0]);
ToServer.flush();
ToServer.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
this.exception = e;
return null;
}
return null;
}}
Я получаю от клиента только сообщение SBA, но никогда не получаю PBA, которое отправляется точно после этого. я закрыл PrintWriter после flush ();
P.S. - когда я печатаю данные на сервере после первого раза, печатается только новая строка, а затем строка «было здесь»
Любые идеи ?
Кстати, если вы делать хотите продолжать использовать тот же сокет, вам нужно использовать какой-то протокол кадрирования, а не просто предполагать, что каждый send на одной стороне будет отображаться как один recv на другой стороне. Сокет TCP - это просто поток байтов, а не поток сообщений. (Хуже всего то, что когда вы тестируете что-то с небольшими сообщениями на localhost, когда машина не занята, она почти всегда будет работать, вводя вас в заблуждение, заставляя думать, что код правильный, но затем большую часть времени терпит неудачу, когда вы развернуть его по-настоящему.)
Я действительно хочу сохранить тот же сокет, однако, я новичок в java, поэтому это клиент, который я нашел в сети, и я добавил отправку. я тоже думал, что это было странно. каждый раз, когда я хочу отправить для создания нового сокета после использования sendmessage.excute (string ..)
Можете ли вы дать мне еще один совет о том, как это настроить, это самая важная вещь, которую нужно сделать в моем проекте.
Если вы хотите повторно использовать один и тот же сокет, вам необходимо изменить код Java, чтобы вы открывали сокет и средство записи потокового кода один раз, удерживали их и повторно использовали в каждой задаче SendMessage. Я уверен, что в Интернете есть хорошие образцы этого, но я понятия не имею, где их найти.
Что касается кадрирования - самый простой вариант - просто разделить сообщения символами новой строки. Это означает, что вам нужно избегать любых символов новой строки в ваших сообщениях (если только их никогда не может быть), но в остальном клиентская сторона - это что-то вроде ToServer.print(params[0] + "\n"); (или, как бы то ни было, вы выполняете конкатенацию строк в Java), а на стороне сервера можно просто использовать for data in client_socket.makefile(encoding='utf-8'):. (Вам также понадобится некоторая обработка ошибок, логика повторного подключения и т. д., Но это поможет вам начать.)
Вы думаете, что изменение сервера на многопоточность решит проблему? Я предпочитаю искать решение на Python вместо java.
Абарнерт уже указывал на большинство проблем. Я просто хочу уточнить, что в некоторых ситуациях вам нужно позаботиться о многопоточности вашего приложения. Например, вы можете запустить server_socket.accept() в его собственном потоке, который создаст новый поток, который будет обрабатывать соединение. Однако каждый новый поток будет иметь собственный клиентский сокет. Если вы не измените код Java, это приведет к соединению полуоткрытый, поскольку сервер не заметит, что клиент умер.




Похоже, ваш клиент подключается, отправляет сообщение, а затем отключается каждый раз, когда вы хотите отправить сообщение. Но ваш сервер выполняет однократное принятие и постоянно пытается читать из одного и того же сокета. Если вы хотите новое соединение для каждого сообщения, вам нужно новое подтверждение для каждого сообщения; если вы хотите продолжать использовать одну и ту же розетку, вы должны сделать это с обеих сторон.