Multithreading Golang中的多线程套接字连接

Multithreading Golang中的多线程套接字连接,multithreading,go,Multithreading,Go,背景 我正在使用Golang创建聊天室服务器。每次客户机连接到服务器时,我都会将客户机函数作为一个新线程启动,这样每个客户机都会得到一个被监听的线程。我能够基于创建一个简单的客户机-服务器连接,但现在我正在尝试为多个客户机创建连接,以便他们可以向聊天室发送消息 代码解释 通过下面的步骤,看起来我可以使用go func()创建一个线程,并通过包含一个通道来等待建立连接(理解这里的区别非常重要:这是并发,而不是多线程,这些是goroutine,而不是线程。这些概念是不可互换的。至于您的核心问题,您的

背景

我正在使用Golang创建聊天室服务器。每次客户机连接到服务器时,我都会将客户机函数作为一个新线程启动,这样每个客户机都会得到一个被监听的线程。我能够基于创建一个简单的客户机-服务器连接,但现在我正在尝试为多个客户机创建连接,以便他们可以向聊天室发送消息

代码解释


通过下面的步骤,看起来我可以使用
go func()
创建一个线程,并通过包含一个通道来等待建立连接(
理解这里的区别非常重要:这是并发,而不是多线程,这些是goroutine,而不是线程。这些概念是不可互换的。至于您的核心问题,您的实现存在一些重大问题:

  • 您正在启动一个goroutine,该goroutine关闭在循环迭代中共享的变量,关键是
    conn
    。每次接受连接时,您都会覆盖每个goroutine共享的
    conn
    。您应该将
    conn
    传递给您的goroutine,使其具有自己的本地副本,或者创建一个新的
    c在每个循环迭代中使用onn
    变量,而不是重复使用一个
  • 您在每次循环迭代中都会启动一个新的侦听器,这将失败,因为旧的侦听器仍在使用该端口。您不需要新的侦听器。只需在现有侦听器上继续调用
    ln.Accept
    ,即可继续接受新的连接。请查看文档的介绍,或检查任何cod以Go中使用侦听器的e为例
  • 您正在goroutine内部创建
    newClient
    ,然后尝试在goroutine外部引用它。这甚至不会编译,而且不清楚您首先要用这个频道做什么
查看一些现有的网络代码-在
net
net/http
库或GitHub上的一些流行项目中-看看如何编写网络应用程序的好例子。在web上搜索博客文章、教程或指南,有很多。一定要阅读软件包的文档如果你正在使用,它将对你有很大帮助

package main

import (
    "net"
    "fmt"
    "bufio"
    "strings" 
    "container/list"
    "time"
)

type chatRoom struct {
    name string
    messages list.List
    users list.List
    lastUsed time.Time
}

var chatRooms *list.List    //A list of chatrooms where each client can post messages, where messages can be seen by all clients in the chatroom
var conn net.Conn

func user(conn net) {
    for {
        message, _ := bufio.NewReader(conn).ReadString('\n')    // will listen for message to process ending in newline (\n)
        fmt.Print("Message Received:", string(message))     // output message received
        s := strings.Split(string(message), ":")
        if strings.Compare(s[0],"create") == 0{    //create a chat room
            create(conn, s[1])
        }else if strings.Compare(s[0],"list") == 0 {   //List the current chatrooms
            msg = listRooms(conn)
        }else if strings.Compare(s[0],"join") == 0 {   //Join the user to a chat room
            join(conn, s[1])
        }else if strings.Compare(s[0],"leave") == 0 {  //Remove the user from a chatroom
            leave(conn, s[1])
        }else if strings.Compare(s[0],"message") == 0{ //Send a message to a chatroom
            message(conn, s[1], s[2])
        }
    }
}

func main() {

    fmt.Println("Launching server...")
    this.userList = list.New()
    this.chatRooms = list.New();

    ln, _ := net.Listen("tcp", ":8081")             // listen on all interfaces
    conn, _ := ln.Accept()                      // accept connection on port

    for {                               // run loop forever (or until ctrl-c)
        go func(){
            newClient := make(chan bool)                        
            ln, _ := net.Listen("tcp", ":8081")         // listen on all interfaces
            conn, _ := ln.Accept()                  // accept connection on port
            newClient <- true
            user(conn)
        }
        <-newClient
    }
}