go+tcp网络编程

127.0.0.1这个IP是不能与127.0.0.1以外的IP进行通讯的,因为127.0.0.1这个IP不经过网络接口,所以只能和本地通信,也就是只能和127.0.0.1进行通信,目的地址和源地址都是127.0.0.1时,程序通过端口在不同的进程间进行通信, 解释下redis绑定127.0.0.1的时候非本机不能访问的案例

1.字节对齐

64位机器默认是8字节对齐的

int32 长度为4, int 在32位os上是4个字节,64位是8个字节
bool 类型虽然只有一位,但也需要占用1个字节,因为计算机是以字节为单位
64为的机器,一个 int 占8个字节
string 类型占16个字节,内部包含一个指向数据的指针(8个字节)和一个 int 的长度(8个字节)
slice 类型占24个字节,内部包含一个指向数据的指针(8个字节)和一个 int 的长度(8个字节)和一个 int 的容量(8个字节)
map 类型占8个字节,是一个指向 map 结构的指针
可以用 struct{} 表示空类型,这个类型不占用任何空间,用这个作为 map 的 value,可以讲 map 当做 set 来用

 

2.net

2.1 (b *Writer) Flush()  是同步还是异步的?发送缓冲区满了如何?(不报错,继续发?) 发送超时时间?
发送缓冲区满了,不会返回目前已经发送的数据大小,在net库中会返回EAGAIN"阻塞"当前goroutine,直到epoll检查到该socket上有可读信号,比如socket关闭,缓冲区可写等
if err == syscall.EAGAIN && fd.pd.pollable() /usr/local/Cellar/go/1.12.6/libexec/src/internal/poll/fd_unix.go 275行

gopark函数调用了mcall的函数,该函数用汇编来实现,具体功能就是把当前的goroutine挂起,然后去执行其他可执行的goroutine。到这里整个goroutine挂起的过程已经结束,那当goroutine可读的时候是如何通知该goroutine呢,这就是epoll的功劳了。

http://www.opscoder.info/golang_netpoller.html

https://www.jb51.net/article/124602.htm

2.2

timeout本身通过 net.Conn包中的Set[Read|Write]Deadline(time.Time)方法来控制  
SetWriteDeadline从设置的时候立即生效,conn超时后不会立即断开, 在发送数据前会对conn做检查:  prepareWrite 的时候会直接返回poll.TimeoutError,
而且Writer中也记录了error信息, 个人觉得一旦出现timeout,也不要想着去恢复这个conn了,因为你也不知道究竟写了多少字节数据出去,还是断链重连后重新发送数据包吧
为啥加超时后这么慢,看下addtimer 的实现,timer 是个四叉小顶堆,每次添加一个超时,最后都需要对一个全局的timers 进行加锁,当qps 很高,一个请求,多次加锁,这性能能很高吗?
https://my.oschina.net/u/2950272/blog/2247104?origin=wechat

案例:  GoBelieveIO  中 im/connection.go 对读写都设置了超时

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值