Go语言简单的TCP编程
2013-09-17 23:36
495 查看
前期准备
需要import "net"包
IP类型,其中一个重要的方法是
IP.ParseIP(ipaddr string)来判断是否是合法的IP地址
TCP Client
func (c *TCPConn) Write(b []byte) (n int, err os.Error)用于发送数据,返回发送的数据长度或者返回错误,是
TCPConn的方法
func (c *TCPConn) Read(b []byte) (n int, err os.Error)用于接收数据,返回接收的长度或者返回错误,是
TCPConn的方法
TCPAddr类型,保存TCP的地址信息,包括地址和端口
type TCPAddr struct { IP IP Port int }
func ResolveTCPAddr(net, addr string) (*TCPAddr, os.Error)获取一个
TCPAddr,参数都是
string类型,net是个
const string,包括
tcp4,
tcp6,
tcp一般使用
tcp,兼容v4和v6,
addr表示ip地址,包括端口号,如
www.google.com:80之类的
func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err os.Error)用来连接(connect)到远程服务器上,net表示协议方式,
tcp,
tcp4或者
tcp6,
laddr表示本机地址,一般为
nil,
raddr表示远程地址,这里的
laddr和
raddr都是
TCPAddr类型的,一般是上一个函数的返回值。
作为一个TCP的客户端,基本的操作流程如下:
service="www.google.com:80" tcpAddr, err := net.ResolveTCPAddr("tcp4", service) conn, err := net.DialTCP("tcp", nil, tcpAddr) _, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n")) _, err = conn.Read(b) / result, err := ioutil.ReadAll(conn)
TCP Server
func ListenTCP(net string, laddr *TCPAddr) (l *TCPListener, err os.Error)用来监听端口,
net表示协议类型,
laddr表示本机地址,是
TCPAddr类型,注意,此处的laddr包括端口,返回一个
*TCPListener类型或者错误
func (l *TCPListener) Accept() (c Conn, err os.Error)用来返回一个新的连接,进行后续操作,这是
TCPListener的方法,一般
TCPListener从上一个函数返回得来。
服务器的基本操作流程为:
service:=":9090" tcpAddr, err := net.ResolveTCPAddr("tcp4", service) l,err := net.ListenTCP("tcp",tcpAddr) conn,err := l.Accept() go Handler(conn) //此处使用go关键字新建线程处理连接,实现并发
一个例子
需求
实现一个公共聊天服务器。服务器接收客户端的信息
接收完以后将客户端的信息发送到所有的客户端上
客户端使用
/quit退出聊天
只使用一套代码,通过命令行参数启动服务器还是客户端
实现:
package main import( "fmt" "os" "net" ) //////////////////////////////////////////////////////// // //错误检查 // //////////////////////////////////////////////////////// func checkError(err error,info string) (res bool) { if(err != nil){ fmt.Println(info+" " + err.Error()) return false } return true } //////////////////////////////////////////////////////// // //服务器端接收数据线程 //参数: // 数据连接 conn // 通讯通道 messages // //////////////////////////////////////////////////////// func Handler(conn net.Conn,messages chan string){ fmt.Println("connection is connected from ...",conn.RemoteAddr().String()) buf := make([]byte,1024) for{ lenght, err := conn.Read(buf) if(checkError(err,"Connection")==false){ conn.Close() break } if lenght > 0{ buf[lenght]=0 } //fmt.Println("Rec[",conn.RemoteAddr().String(),"] Say :" ,string(buf[0:lenght])) reciveStr :=string(buf[0:lenght]) messages <- reciveStr } } //////////////////////////////////////////////////////// // //服务器发送数据的线程 // //参数 // 连接字典 conns // 数据通道 messages // //////////////////////////////////////////////////////// func echoHandler(conns *map[string]net.Conn,messages chan string){ for{ msg:= <- messages fmt.Println(msg) for key,value := range *conns { fmt.Println("connection is connected from ...",key) _,err :=value.Write([]byte(msg)) if(err != nil){ fmt.Println(err.Error()) delete(*conns,key) } } } } //////////////////////////////////////////////////////// // //启动服务器 //参数 // 端口 port // //////////////////////////////////////////////////////// func StartServer(port string){ service:=":"+port //strconv.Itoa(port); tcpAddr, err := net.ResolveTCPAddr("tcp4", service) checkError(err,"ResolveTCPAddr") l,err := net.ListenTCP("tcp",tcpAddr) checkError(err,"ListenTCP") conns:=make(map[string]net.Conn) messages := make(chan string,10) //启动服务器广播线程 go echoHandler(&conns,messages) for { fmt.Println("Listening ...") conn,err := l.Accept() checkError(err,"Accept") fmt.Println("Accepting ...") conns[conn.RemoteAddr().String()]=conn //启动一个新线程 go Handler(conn,messages) } } //////////////////////////////////////////////////////// // //客户端发送线程 //参数 // 发送连接 conn // //////////////////////////////////////////////////////// func chatSend(conn net.Conn){ var input string username := conn.LocalAddr().String() for { fmt.Scanln(&input) if input == "/quit"{ fmt.Println("ByeBye..") conn.Close() os.Exit(0); } lens,err :=conn.Write([]byte(username + " Say :::" + input)) fmt.Println(lens) if(err != nil){ fmt.Println(err.Error()) conn.Close() break } } } //////////////////////////////////////////////////////// // //客户端启动函数 //参数 // 远程ip地址和端口 tcpaddr // //////////////////////////////////////////////////////// func StartClient(tcpaddr string){ tcpAddr, err := net.ResolveTCPAddr("tcp4", tcpaddr) checkError(err,"ResolveTCPAddr") conn, err := net.DialTCP("tcp", nil, tcpAddr) checkError(err,"DialTCP") //启动客户端发送线程 go chatSend(conn) //开始客户端轮训 buf := make([]byte,1024) for{ lenght, err := conn.Read(buf) if(checkError(err,"Connection")==false){ conn.Close() fmt.Println("Server is dead ...ByeBye") os.Exit(0) } fmt.Println(string(buf[0:lenght])) } } //////////////////////////////////////////////////////// // //主程序 // //参数说明: // 启动服务器端: Chat server [port] eg: Chat server 9090 // 启动客户端: Chat client [Server Ip Addr]:[Server Port] eg: Chat client 192.168.0.74:9090 // //////////////////////////////////////////////////////// func main(){ if len(os.Args)!=3 { fmt.Println("Wrong pare") os.Exit(0) } if os.Args[1]=="server" && len(os.Args)==3 { StartServer(os.Args[2]) } if os.Args[1]=="client" && len(os.Args)==3 { StartClient(os.Args[2]) } }
相关文章推荐
- Go语言简单的TCP编程
- Go语言并发编程简单入门
- GO语言网络编程之TCP (v2)
- Go语言TCP Socket编程
- go语言网络编程之tcp
- Go语言实现的简单TCP服务及使用MySql
- GO语言TCP编程范式
- Go语言TCP Socket编程
- Go语言最简单的tcp server/client
- GO语言网络编程之TCP (v1)
- GO语言tcpip 编程
- Go语言中Tcp协议粘包问题处理
- 网络编程之:TCP服务器的简单实现
- [C++] Windows下的socket编程(这是一个简单的TCP/IP例子)
- GO语言如何手动处理TCP粘包详解
- 简单看懂GO语言并发
- Go语言基础学习九-过程式编程一
- 基于TCP模式的socket编程 简单封装
- GO 语言编程 windows 环境搭建
- socket编程,先来个简单的TCP例子吧