这里给出一个服务端和客户端,服务端可以接受多个连接,并且利用Go的杀手特性go和channel来替代select进行数据的接收。
服务端:
package main
import (
"fmt"
. "syscall"
)
func RecvRoutine(sockfd int,session chan string) {
var buffer []byte = make([]byte,3000)
for {
if length,err := Read(sockfd,buffer); err == nil {
session <- string(buffer[:length])
}
}
}
func main() {
var (
serversock int
serveraddr SockaddrInet4
session chan string = make(chan string,1000)
err error
)
if serversock,err = Socket(AF_INET,SOCK_STREAM,IPPROTO_IP); err != nil {
fmt.Println("Server Socket() called error:",err.Error())
return
}
defer Shutdown(serversock,SHUT_RDWR)
serveraddr.Addr = [4]byte{127,1}
serveraddr.Port = 3000
if err = Bind(serversock,&serveraddr); err != nil {
fmt.Println("Server Bind() called error:",err.Error())
return
}
if err = Listen(serversock,SOMAXCONN); err != nil {
fmt.Println("Server Listen() called error:",err.Error())
return
}
go func() {
for {
fmt.Println(<-session)
}
}()
fmt.Println("server is listening at port 3000...")
for {
if clientsock,_,err := Accept(serversock); err == nil {
go RecvRoutine(clientsock,session)
}
}
}
客户端:
package main
import (
"fmt"
. "syscall"
)
func main() {
var (
clientsock int
serveraddr SockaddrInet4
err error
)
if clientsock,IPPROTO_IP); err != nil {
fmt.Println("Client Socket() called error:",err.Error())
return
}
defer Shutdown(clientsock,1}
serveraddr.Port = 3000
if err = Connect(clientsock,&serveraddr); err != nil {
fmt.Println("Client Connect() called error:",err.Error())
return
}
var msg string
for {
fmt.Scanf("%s\r\n",&msg)
if msg != "\r" && msg != "\n" {
if _,err = Write(clientsock,[]byte(msg)); err != nil {
fmt.Println("Send() error:",err.Error())
}
}
}
}