2016-03-29 16 views
0

Мне нужен клиент и сервер для связи через сокет. Клиент сообщает серверу, что он хочет получить конкретное сообщение (через строку «arquivo») и получает сообщение длиной 10 КБ. Оба из них должны поддерживать соединение открытым, если клиент хочет снова запросить сообщение с той же строкой. Я мог бы реализовать это для 1 обмена, закрывая соединение. Когда я вставлял некоторое время, сервер, очевидно, отправляет сообщение, но он никогда не попадает на клиент, если я не закрываю окно терминала, в котором работает клиент. Я запускал их в отдельном окне терминала и тестировал код клиента на сервере, который только передает сообщение один раз, а затем закрывает соединение, и сообщение прошло. Код проблематичного сервера выглядит следующим образом:Проблема с сервером Lua TCP при использовании цикла для приема и отправки сообщений несколько раз

filename = "file10KB.txt" 
file = assert(io.open(filename, "r")) 
msg = file:read("*a") 
file:close() 

socket = require("socket") 

host = "*" 
port = 8080 

print("Binding to host '" .. host .. "' and port " .. port .. "...") 

server = assert(socket.bind(host, port)) 
server:setoption("reuseaddr", true) 
ipaddress, socketport = server:getsockname() 
assert(ipaddress, socketport) 

print("Waiting connection from client on " .. ipaddress .. ":" .. socketport .. "...") 

connection = assert(server:accept()) 
connection:setoption("keepalive", true) 
connection:settimeout(10) 

print("Connected!") 

while true do 
    print("Waiting for request...") 
    data, errormsg = connection:receive() 

    if data == "arquivo" then 
     print("Proper request received, sending message...") 
     assert(connection:send(msg .. "\n")) 
     print("Message sent!") 
    elseif not errormsg then 
     print("Invalid request.") 
     break 
    else 
     print("Error message: " .. errormsg) 
     break 
    end 
end 

Кроме того, код моего клиента:

socket = require("socket") 

host = "localhost" 
port = 8080 

print("Attempting connection to server '" .. host .. "' and port " .. port .. "...") 

client = assert(socket.connect(host, port)) 

client:setoption("keepalive", true) 
client:setoption("reuseaddr", true) 
client:settimeout(10) 

print("Connected!") 

repeat 
    print("Sending message request...") 
    assert(client:send("arquivo" .. "\n")) 

    print("Message request sent! Waiting for message...") 
    data, errormsg = client:receive("*a") 

    if data then 
     print("Message received!") 
     print(data) 
    else 
     print("Failed to receive message.") 
     break 
    end 
until not client 

Я новичок в Lua и к розеткам и я последовал за некоторые уроки, которые я нашел в Интернете, например, http://www.portugal-a-programar.pt/topic/36175-aprendendo-a-usar-lua-socket/ (он находится на португальском языке). Я просто надеюсь, что любой из вас может пролить свет на то, что мне не хватает. Кстати, я использую Mac OS X, не знаю, поможет ли это.

ответ

0

Когда я кладу в то время, хотя, сервер, видимо, посылает сообщение, но оно никогда не дойдет до клиента, если не закрыть окно терминала, где клиент работает

Я не знаю, что это значит. Закрытие окна терминала должно закрыть клиент, что вряд ли означает, что он вдруг получит сообщение.

Однако существует множество проблем с этим, слишком долго для комментариев:

  • Вы должны установить SO_REUSEADDR перед тем связывания. Впоследствии слишком поздно.
  • Вам не нужно устанавливать его у клиента вообще, но если вы это сделаете, он должен быть подключен.
  • sockname Проверка на сервере бессмысленна. Это не может потерпеть неудачу.
  • Ваш сервер принимает только одно соединение.
  • Ваш сервер никогда не закрывает соединение.
  • Ваш сервер не распознает конец потока правильно.
  • Ваш клиент никогда не закрывает соединение.
+0

Спасибо за замечания, я исправлю их. Также подумал, что моя проблема, ответит на вопрос ниже. Еще раз спасибо! – eweiner

0

Проблема была в линии

data, errormsg = client:receive("*a") 

в коде клиента. Опция * a принимает только при закрытии соединения и изменении ее на * l или ничего подобного ниже, заставляя ее работать.

data, errormsg = client:receive()