package main
import (
"bufio"
"fmt"
"io"
"log"
"net"
"os"
"strconv"
"strings"
)
var messages chan string
func main() {
messages = make(chan string, 10)
var port int = 3333
listen, err := net.Listen("tcp4", ":"+strconv.Itoa(port))
defer listen.Close()
if err != nil {
log.Fatalf("Прослушивание порта %d не удалось,\r\n\r\n %s", port, err)
os.Exit(1)
}
go func() {
log.Printf("Сервер слушает порт: %d", port)
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
log.Print(text)
messages <- text
}
}()
for {
conn, err := listen.Accept()
if err != nil {
log.Fatalln(err)
continue
}
go handler(conn)
}
}
func handler(conn net.Conn) {
defer conn.Close()
var (
buf = make([]byte, 1024)
r = bufio.NewReader(conn)
w = bufio.NewWriter(conn)
)
ILOOP:
for {
n, err := r.Read(buf)
data := string(buf[:n])
switch err {
case io.EOF:
break ILOOP
case nil:
//log.Println("Получил:", data)
if isTransportOver(data) {
break ILOOP
}
default:
log.Fatalf("Ошибка при получении:%s", err)
return
}
}
//данные из канала
msg := <-messages
w.Write([]byte(msg))
w.Flush()
}
func isTransportOver(data string) (over bool) {
over = strings.HasSuffix(data, "\r\n\r\n")
return
}
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
type Client struct {
writer *bufio.Writer
}
func (client *Client) Write(data string) error {
fmt.Println("client write")
_, err := client.writer.WriteString(data)
err = client.writer.Flush()
return err
}
func NewClient(connection net.Conn) *Client {
writer := bufio.NewWriter(connection)
client := &Client{
writer: writer,
}
return client
}
type ChatRoom struct {
clients []*Client
}
func (chatRoom *ChatRoom) Broadcast(data string) {
deleted := 0
for i := range chatRoom.clients {
j := i - deleted
if err := chatRoom.clients[j].Write(data); err != nil {
fmt.Println(err, "deleted error")
chatRoom.clients = chatRoom.clients[:j+copy(chatRoom.clients[j:], chatRoom.clients[j+1:])]
deleted++
}
}
}
func (chatRoom *ChatRoom) Join(connection net.Conn) {
client := NewClient(connection)
chatRoom.clients = append(chatRoom.clients, client)
}
func NewChatRoom() *ChatRoom {
chatRoom := &ChatRoom{
clients: make([]*Client, 0),
}
return chatRoom
}
func main() {
chatRoom := NewChatRoom()
listener, _ := net.Listen("tcp4", ":3333")
go readAndSend(chatRoom)
for {
conn, err := listener.Accept()
if err != nil {
continue
}
chatRoom.Join(conn)
}
}
func readAndSend(chatRoom *ChatRoom) {
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
log.Print(text)
chatRoom.Broadcast(text)
}
}
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
"strconv"
"strings"
)
var messages chan string
type Client struct {
Id uint64
MsgChan chan (string)
}
type ClientPool struct {
counter uint64
joins chan (Client)
lefts chan (uint64)
ids chan (uint64)
broadcasts chan (string)
clients map[uint64]Client
}
func NewClientPool() *ClientPool {
pool := ClientPool{
joins: make(chan (Client)),
lefts: make(chan (uint64)),
ids: make(chan (uint64)),
broadcasts: make(chan (string)),
clients: make(map[uint64]Client),
}
go func() {
var id uint64
for {
id++
pool.ids <- id
}
}()
go func() {
for {
select {
case newClient := <-pool.joins:
pool.clients[newClient.Id] = newClient
case idForDeletion := <-pool.lefts:
delete(pool.clients, idForDeletion)
case text := <-pool.broadcasts:
for _, client := range pool.clients {
client.MsgChan <- text
}
}
}
}()
return &pool
}
func (this *ClientPool) NewClient() Client {
client := Client{
Id: <-this.ids,
MsgChan: make(chan (string)),
}
this.joins <- client
return client
}
func (this *ClientPool) BroadcastMessage(text string) {
this.broadcasts <- text
}
func (this *ClientPool) DeleteClient(client Client) {
this.lefts <- client.Id
}
func main() {
pool := NewClientPool()
var port int = 3333
listen, err := net.Listen("tcp4", ":"+strconv.Itoa(port))
defer listen.Close()
if err != nil {
log.Fatalf("Прослушивание порта %d не удалось,\r\n\r\n %s", port, err)
os.Exit(1)
}
go func() {
log.Printf("Сервер слушает порт: %d", port)
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
log.Print(text)
pool.BroadcastMessage(text)
}
}()
for {
conn, err := listen.Accept()
if err != nil {
log.Fatalln(err)
continue
}
go handler(conn, pool)
}
}
func handler(conn net.Conn, pool *ClientPool) {
client := pool.NewClient()
defer pool.DeleteClient(client)
defer conn.Close()
defer log.Printf("Клиент с номером %d вышел\n", client.Id)
log.Printf("Новый клиент присоединен, ему присвоен номер %d", client.Id)
incomingClientMsg := make(chan string)
go func() {
reader := bufio.NewReader(conn)
for {
text, err := reader.ReadString('\n')
if err != nil {
close(incomingClientMsg)
return
}
incomingClientMsg <- text
}
}()
for {
select {
case text := <-incomingClientMsg:
text = strings.Trim(text, "\r\n")
if text == "/quit" {
return
}
log.Printf("Клиент с номером %d написал: %s\n", client.Id, text)
case text := <-client.MsgChan:
_, err := conn.Write([]byte(text))
if err != nil {
return
}
}
}
}