2013-09-16 4 views
7

В последнее время я играю с ходу и пытаюсь сделать какой-то сервер, который отвечает клиентам на tcp-подключении.Как я могу прерывать выполнение goroutine (* TCPListener) Accept?

Мой вопрос, как я чисто выключит сервер и прервать идти-подпрограмму, которая в настоящее время «заблокирован» в следующем вызове

Func (* TcpListener) Accept?

Согласно documentation of Accept

Accept реализует метод Accept в интерфейсе приемника; он ждет следующего вызова и возвращает общий разъем.

Ошибки также очень задокументированы.

ответ

3

Вот что я искал. Может быть, помогает кому-то в будущем. Обратите внимание на использование выбора и канал «с», чтобы объединить его с выходным каналом

ln, err := net.Listen("tcp", ":8080") 
    if err != nil { 
     // handle error 
    } 
    defer ln.Close() 
    for { 
     type accepted struct { 
      conn net.Conn 
      err error 
     } 
     c := make(chan accepted, 1) 
     go func() { 
      conn, err := ln.Accept() 
      c <- accepted{conn, err} 
     }() 
     select { 
     case a := <-c: 
      if a.err != nil { 
       // handle error 
       continue 
      } 
      go handleConnection(a.conn) 
     case e := <-ev: 
      // handle event 
      return 
     } 
    } 
3

Просто Close()net.Conn Вы получаете от Accept() звонок и возврат от исполняющей магистратуры.

+0

Хорошо, но тогда как я определить, что акцепт не удалось из-за моих близких, не создавая какой-то конкретный код приложения? Согласно документации http://golang.org/pkg/net/#Error, которую нелегко понять. Ок, может быть, не имеет значения, чем много, но будет больше инкапсулированного потока, если бы я мог знать, что сокет закрыт. – mhstnsc

+1

Принять возвращает два значения: Conn и ошибка. Если ошибка не равна нулю, то что-то не получилось. – thwd

+0

Это я знаю. Но откуда вы знаете, что принятие не подвело по какой-то другой причине, и мне просто нужно повторить попытку? Документация не говорит, что она потерпит неудачу, только если я закрою сокет. Также посмотрите на документацию о принятии posix. http://linux.die.net/man/2/accept. Посмотрите, сколько там ошибок. – mhstnsc

1

Слушатель Дедлайны

Вам не обязательно нужна дополнительная рутина идти (который держит прием), просто указать a Deadline.

for пример:

for { 

    // Check if someone wants to interrupt accepting 
    select { 
    case <- someoneWantsToEndMe: 
     return // runs into "defer listener.Close()" 
    default: // nothing to do 
    } 

    // Accept with Deadline 
    listener.SetDeadline(time.Now().Add(1 * time.Second) 
    conn, err := listener.Accept() 
    if err != nil { 
     // TODO: Could do some err checking (to be sure it is a timeout), but for brevity 
     continue 
    } 

    go handleConnection(conn) 
} 
Смежные вопросы