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