分享
  1. 首页
  2. 文章

[Golang]Socket编程01----实现基本功能的Client和Server

码农小骚年 · · 4313 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

支持多连接。

Server运行之后,进入Accept阻塞状态。Accept得到一个Conn之后,开启一个协程,分别有两个协程阻塞在Read和Write。当Read一个数据之后,将Read得到的数据写入readChannel中,之后再对其进行处理。在writeChannel得到一个数据之后,向Conn写入数据。

Client运行后,接入Server,之后开启两个协程阻塞在Read和Write的Channel中。在Scan得到一个数据之后,向writeChannel写入数据,唤醒阻塞的协程向Conn中写入数据。当Server中有数据返回时,read协程被唤醒,将数据写入readChannel中。

当然,还有诸多细节要处理。比如Conn的关闭在什么时候等等。

客户端源码

package client
import (
	"net"
	"git.oschina.net/sdlszjb/unix_socket/errs"
	"fmt"
)
func StartClient1() {
	tcpAddress, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:1300")
	if err != nil {
		errs.Error_exit(err)
	}
	conn, err := net.DialTCP("tcp", nil, tcpAddress)
	if err != nil {
		errs.Error_exit(err)
	}
	writeChan := make(chan []byte, 1024)
	readChan := make(chan []byte, 1024)
	go writeConnection(conn, writeChan)
	go readConnection(conn, readChan)
	//go handleReadChannel(readChan)
	for {
		var s string
		fmt.Scan(&s)
		writeChan <- []byte(s)
	}
}
func readConnection(conn *net.TCPConn, channel chan []byte) {
	defer conn.Close()
	buffer := make([]byte, 2048)
	for {
		n, err := conn.Read(buffer)
		if err != nil {
			errs.Error_print(err)
			return
		}
		println("Received from:", conn.RemoteAddr(), string(buffer[:n]))
		//channel <- buffer[:n]
	}
}
func writeConnection(conn *net.TCPConn, channel chan []byte) {
	defer conn.Close()
	for {
		select {
		case data := <- channel:
			_, err := conn.Write(data)
			if err != nil {
				errs.Error_exit(err)
			}
			println("Write to:", conn.RemoteAddr(), string(data))
		}
	}
}

服务端代码:

package server
import (
	"net"
	"git.oschina.net/sdlszjb/unix_socket/errs"
	"fmt"
)
var client_num int = 0
func StartServer1() {
	l, err := net.Listen("tcp", ":1300")
	if err != nil {
		errs.Error_exit(err)
	}
	defer l.Close()
	for {
		conn, err := l.Accept()
		if err != nil {
			errs.Error_print(err)
			continue
		}
		client_num++
		fmt.Printf("A new Connection %d.\n", client_num)
		go handlerConnection(conn)
	}
}
func handlerConnection(conn net.Conn) {
	defer closeConnection(conn)
	readChannel := make(chan []byte, 1024)
	writeChannel := make(chan []byte, 1024)
	go readConnection(conn, readChannel)
	go writeConnection(conn, writeChannel)
	for {
		select {
		case data := <- readChannel:
			if string(data) == "bye" {
				return
			}
			writeChannel <- append([]byte("Back"), data...)
		}
	}
}
func writeConnection(conn net.Conn, channel chan []byte) {
	for {
		select {
		case data := <- channel:
			println("Write:", conn.RemoteAddr().String(), string(data))
			_, err := conn.Write(data)
			if err != nil {
				errs.Error_print(err)
				return
			}
		}
	}
}
func readConnection(conn net.Conn, channel chan []byte) {
	buffer := make([]byte, 2048)
	for {
		n, err := conn.Read(buffer)
		if err != nil {
			errs.Error_print(err)
			channel <- []byte("bye")	//这里须要进一步改进!
			break
		}
		println("Recei:", conn.RemoteAddr().String(), string(buffer[:n]))
		channel <- buffer[:n]
	}
}
func closeConnection(conn net.Conn) {
	conn.Close()
	client_num--
	fmt.Printf("Now, %d connections is alve.\n", client_num)
}

有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:码农小骚年

查看原文:[Golang]Socket编程01----实现基本功能的Client和Server

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
4313 次点击
1 回复 | 直到 2025年05月15日 08:33:41
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏