如果函数成功,则返回0,创建好的套接字分别是sv[0]和sv[1];否则返回-1,错误码保存于errno中。 基本用法: 1. 这对套接字可以用于全双工通信,每一个套接字既可以读也可以写。...例如,可以往sv[0]中写,从sv[1]中读;或者从sv[1]中写,从sv[0]中读; 2....如果往一个套接字(如sv[0])中写入后,再从该套接字读时会阻塞,只能在另一个套接字中(sv[1])上读成功; 3. 读、写操作可以位于同一个进程,也可以分别位于不同的进程,如父子进程。...如果是父子进程时,一般会功能分离,一个进程用来读,一个用来写。因为文件描述副sv[0]和sv[1]是进程共享的,所以读的进程要关闭写描述符, 反之,写的进程关闭读描述符。..., recvmsg , send函数的使用 sendmsg, recvmsg , send三个函数的头文件: #include #include <sys/socket.h
如果函数成功,则返回0,创建好的套接字分别是sv[0]和sv[1];否则返回-1,错误码保存于errno中。 基本用法: 1. 这对套接字可以用于全双工通信,每一个套接字既可以读也可以写。...例如,可以往sockfd[0]中写,从sockfd[1]中读;或者从sockfd[1]中写,从sockfd[0]中读; 2....如果往一个套接字(如sockfd[0])中写入后,再从该套接字读时会阻塞,只能在另一个套接字中(sockfd[1])上读成功; 3....读、写操作可以位于同一个进程,也可以分别位于不同的进程,如父子进程。如果是父子进程时,一般会功能分离,一个进程用来读,一个用来写。...因为文件描述符sockfd[0]和sockfd[1]是进程共享的,所以读的进程要关闭写描述符, 反之,写的进程关闭读描述符。
TCP接收到一个根本不存在的连接上的分节; 现在模拟上面的三种情况: client: struct sockaddr_in serverAdd; bzero(&serverAdd,...当一个进程向某个已收到RST的套接字执行写操作时,(此时写操作返回EPIPE错误)内核向该进程发送一个SIGPIPE信号,该信号的默认行为是终止进程,因此进程必须捕获它以免不情愿地被终止; 继续修改客户端程序如下...字节以后先休眠一秒是为了将数据发送出去,确认TCP协议层已收到服务端响应的RST分节,然后再进行读操作,此时read返回-1.而不再是0; 先运行服务端,再运行客户端,客户端打印信息如下: 发送成功...,(此时读操作返回ECONNRESET错误) 抓包信息如下: 上述情况会引发一个问题:服务器主机进程终止或者崩溃后重启,客户端在不write的情况下不会知道,read会返回ECONNRESET错误或者超时...如果对端TCP发送一个RST(对端主机崩溃并重新启动),那么该套接字变为可读,并且read返回-1,而errno中含有确切的错误码; 这个问题在select详解中讲述 情况三: 修改客户端程序如下,服务端不变
ssize_t send(int sockfd, void * buff, size_t nbytes, int flags); //返回: 成功返回读入或写出的字节数,出错返回-1 flag在设计上存在一个基本问题...3.readv和writev函数(分散读,集中写) #include ssize_t readv(int filedes, const struct iovec * iov, int...4.recvmsg和sendmsg函数 这两个函数是最通用的I/O函数,实际上,可以用recvmsg代替read, readv, recv, recvfrom....(int sockfd, struct msghdr * msg, int flags); //返回: 成功时为读入或写出的字节数,出错时为-1 两个函数把大部分参数都包装到一个msghdr结构中: struct...() */ }; 5.辅助数据 辅助数据(ancillary data)可以通过sendmsg和recvmsg这两个函数,使用msghdr结构中的msg_contorl和msg_controllen成员发送和接收
这是一个生产者消费者模型,生产者是操作系统的网络模块,消费者是多个 Slave 进程,队列中的对象是客户端套接字。...但是不存在竞争问题,因为负责 accept 套接字的只能是 Master 进程,Slave 进程只负责处理客户端套接字请求。...那就存在一个问题,Master 进程拿到的客户端套接字如何传递给 Slave 进程。 ? 这时,神奇的 sendmsg 登场了。它是操作系统提供的系统调用,可以在不同的进程之间传递文件描述符。...因为 sendmsg 和 recvmsg 方法到了 Python3.5 才内置进来,所以下面的代码需要使用 Python3.5+才可以运行。...思考题 sendmsg/recvmsg 除了可以发送描述符外还可以用来干什么? sendmsg/recvmsg 发送接收描述符在内核态具体是如何工作的?
在msghdr结构中的msg_flags成员上设置MSG_TRUNC标志。...这要求应用进程调用recvmsg来接收这个标志。 2. 丢到超出的字节但不通知应用进程。 3. 保留超出的字节并在随后这个套接口上的读操作中返回这些数据。...应答式应用程序中使用UDP,那么我们必须对我们的客户增加两个特性: 超时和重传以处理丢失的数据报 序列号,这样客户可以验证一个应答是对应相应的请求的 这两个特性是多数使用简单的请求-应答范例的现有UDP应用程序的一部分...在这种情形里,读客户请求的服务器可以fork一个子进程去处理请求。“请求”(也就是数据报的内容和保存在客户协议地址中的套接口地址结构)通过从fork得来的内存映像传递给子进程。...dst IPv6 address */ int ipi6_ifindex; /* send / recv interface index */ }; 发送该信息不要什么特别的要求:只是给sendmsg
NIO 通道是面向缓冲的,所以向管道中写入数据也需要和缓冲区配合才行。示例如下 String data = "Test data..."...如果代码按照上面那样去写,会引发另外一个问题。非阻塞模式虽然不会阻塞线程,但是在方法返回后,还要进行循环检测,线程实际上还是被阻塞。...另外,大家还需要去参考一下权威资料《UNIX网络编程卷 第1卷:套接口API》第6章关于 IO 模型的介绍,那一章除了对5种 IO 模型进行了介绍,还介绍了同步与异步的概念,值得一读。...上面有两个方法没有贴代码,就是sendMsg和recvMsg,由于通用操作,在下面的客户端代码里也可以使用,所以这里做了封装。...package wetalk; import static wetalk.WeTalkUtils.recvMsg; import static wetalk.WeTalkUtils.sendMsg;
这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍。(>﹏<) 本学期Linux、unix网络编程的第四个作业。...主线程循环接收客户连接请求,在ent中查询状态为0的元素, 如果不存在状态为0的元素(即连接数超过最大连接数),向客户发送EXIT标志; 否则,修改客户信息表中该元素的socket描述符...bzero(&sendMsg,sizeof(sendMsg)); 125 bzero(&recvMsg,sizeof(recvMsg)); 126 int len =recv...} 149 bcopy(recvMsg.username,sendMsg.username,strlen(recvMsg.username)); 150...bcopy(recvMsg.buf,sendMsg.buf,strlen(recvMsg.buf)); 151 int i; 152 for(i=0;i<
通信协议族在文件sys/socket.h中定义。 ?...绑定本地的相关信息 bindAddr = ('', 7788) # ip地址和端口号,ip一般不用写,表示本机的任何一个ip udpSocket.bind(bindAddr) num = 1 while...= input('--') sendMsg = sendMsg.encode('gb2312') udpSocket.sendto(sendMsg,destAdress) recvMsg=udpSocket.recvfrom...(1024) recvMsg='【Receive from %s : %s 】: %s'%(recvMsg[1][0],recvMsg[1][1],recvMsg[0].decode('gbk')) print...对象 udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) ''' 绑定, 第一个参数是本地ip,不指定也可以,默认会帮你填充,建议不写
导入包的方式 现有以下包newmsg,包里由两个模块,分别是sendmsg.py、recvmsg.py文件。...目录结构如下图所示: - newmsg/ - __init__.py - sendmsg.py - recvmsg.py - test.py sendmsg.py文件里的内容如下: def...send_msg(): print('------sendmsg方法被调用了-------') recvmsg.py文件里的内容如下: def recv_msg(): print('-----recvmsg...init.py为空仅仅是把这个包导入,不会导入包中的模块。可以在__init__.py文件中编写内容。...newmsg/init.py文件: __all__ = ['sendmsg','recvmsg'] 注意事项 在自定义模块时,需要注意一点,自定义模块名不要和系统的模块名重名,否则会出现问题!
我相信我读者大部分都是做互联网应用开发的,可能对游戏的架构不太了解。 我们想象中的游戏架构是下面这样的。 想象中的游戏架构 也就是用户客户端直接连接游戏核心逻辑服务器,下面简称GameServer。...tcp_sendmsg 逻辑 从tcp_sendmsg的代码中可以看到,在对socket的缓冲区执行写操作的时候,linux内核已经自动帮我们加好了锁,也就是说,是线程安全的。...再看下udp的接收函数udp_recvmsg,会发现情况也类似,这里就不再赘述。 能否多线程同时并发读或写同一个UDP socket?...所以从这个角度来说,UDP写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有TCP的问题。...UDP写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有TCP的问题。
最近一直在研究 eBPF ,随着研究的深入,我发现之前写的这篇文章有点问题,所以重新修改了一下。图也重新画了,并添加了一些与 sidecar-less 相关的额外内容。 下面是正文。...比如把 recvmsg 由原来的 tcp_recvmsg 替换成了 tcp_bpf_recvmsg ,而把 tcp_sendmsg 替换为 tcp_bpf_sendmsg 。...发送数据 在和 Process B 成功建立起 TCP 连接后,进程 envoy 开始写数据了,如图 5 中 2.1 所示。...所以这里的主角其实是 tcp_bpf_sendmsg() 。 图 5:发送数据流程 我在图 5 中画出了 tcp_bpf_sendmsg() 所干的几件重要的事情。...我管 tcp_sendmsg() 和 tcp_recvmsg() 叫备胎。因为 tcp_bpf_sendmsg() 以及 tcp_bpf_recvmsg() 在处理一些异常情况时就直接走老路了。
由于大部分游戏都使用 TCP 做开发,所以下面提到的连接,如果没有特别说明,那都是指 TCP 连接。 那么问题来了。...tcp_sendmsg 逻辑 从tcp_sendmsg的代码中可以看到,在对 socket 的缓冲区执行写操作的时候,linux 内核已经自动帮我们加好了锁,也就是说,是线程安全的。...再看下UDP的接收函数udp_recvmsg,会发现情况也类似,这里就不再赘述。 能否多线程同时并发读或写同一个UDP socket?...所以从这个角度来说,UDP 写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有 TCP 的问题。...UDP 写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有 TCP 的问题。
对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息; 对消息队列有读权限的进程则可以从消息队列中读走消息。 消息队列是随内核持续的。...使用msgget( ) 创建/获取消息队列,返回值是队列标识符 (3)使用msgsnd( ) 发送消息 使用msgrcv( ) 接收消息 (4)使用msgctl( ) 删除消息队列 4,实例: sendmsg.c... 用来发送消息的 // sendmsg.c #include #include #include #include<sys/types.h...msgid, IPC_RMID, NULL)) { perror("shmctl failed"); exit(2); } return 0; } recvmsg.c... 用来接收消息的 // recvmsg.c #include #include #include #include
(2)通信子进程: 创建一个子进程负责从消息队列中读取消息,发送给客户。...sendMsg),0); 208 } 209 } 210 else{ 211 while(1){ 212 bzero(&recvMsg...,sizeof(recvMsg)); 213 int len =recv(connetfd,&recvMsg,sizeof(recvMsg),0); 214...semaphore.c clean: rm -rf *.o 下面上一下演示过程:(测试环境,Red Hat Enterprise Linux 6 + centos系Linux,ubuntu下可能会有些问题...本来都想放弃了,但是后来还是咬咬牙坚持了一下来,饭要一口一口吃,程序要一点一点的写,万事不能操之过急,写代码一定要心平气和,头脑清晰。
补充:pipe创建的匿名管道的半双工的,pipefd[0]用于读,pipefd[1]用于写。 注意:由于创建的每个套接字都是没有名字的,这就意味着无关进程不能使用它们。...和recvmsg函数: #include #include ssize_t sendmsg(int...sockfd, const struct msghdr *msg, int flags); ssize_t recvmsg(int sockfd, struct msghdr *msg,...(sock_fd, &msg, 0); if(ret < 0) ERR_EXIT("sendmsg"); } int recv_fd(const int sock_fd) {...(fd < 0) ERR_EXIT("open"); send_fd(sockfds[1], fd); } return 0; } 分析:子进程中打开一个文件描述符
但是没有说stream的实现方式,感觉单独写一篇帖子来说这个更好一些。上一篇帖子是基础,理解了上一篇,stream实现原理一点即破。先说一下使用方式,再说原理。...代码都在github上: 比如我的例子中定义了两个使用stream的接口,一个只在返回值使用stream,另一个是在参数和返回值前都加上了stream,最终的使用方式没有区别 rpc...} type Say_BidirectionalStreamStream interface { SendMsg(interface{}) error RecvMsg(interface...) } type Say_BidirectionalStreamService interface { SendMsg(interface{}) error RecvMsg(interface...Send(你的参数),如果有接收会生成Rev() (你的参数, error),但这两个方法只是为了让你使用时方便,里面调用的还是SendMsg(interface)和RecvMsg(interface)
大部分高性能网络框架采用的是非阻塞模式。笔者这次就从linux源码的角度来阐述socket阻塞(block)和非阻塞(non_block)的区别。...= tcp_sendmsg, .recvmsg = sock_common_recvmsg, ...... } 即sock->ops->recvmsg = sock_common_recvmsg...tcp_v4_connect, .disconnect = tcp_disconnect, .accept = inet_csk_accept, ...... // 我们重点考察tcp的读...; 上述代码中sock关联的file中获取其f_flags,如果flags有O_NONBLOCK标识,那么就设置msg_flags为MSG_DONTWAIT(不等待)。...0 : sk->sk_rcvtimeo; timeo = sock_rcvtimeo(sk, nonblock); ...... // 如果设置了MSG_WAITALL标识target=需要读的长度
1 套接字描述符 套接字描述符在Unix系统中是用文件描述符实现的。...其次,有时只关闭套接字双向传输中的一个方向会很方便。比如,如果想让进程确定数据发送何时结束,可以关闭该套接字的写端,而读端仍然可以接收数据。...寻址 大端,是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中; 小端,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。...Returns: file (socket) descriptor if OK, 1 on error 4 数据传输 三个函数用来发送数据,三个用于接收数据 三个发送数据send,sendto,sendmsg...返回时,该整数设为该地址的实际字节大小 为了将接收到的数据送入多个缓冲区,或者想接收辅助数据,可以使用recvmsg #include ssize_t recvmsg(int
非常的巧妙,它把 struct proto 里面的 recvmsg / sendmsg 等函数动态替换掉了。...比如把 recvmsg 由原来的 tcp_recvmsg 替换成了 tcp_bpf_recvmsg ,而把 tcp_sendmsg 替换为 tcp_bpf_sendmsg 。...发送数据 ---- 在和 Process B 成功建立起 TCP 连接后,进程 envoy 开始写数据了,如图 5 中 2.1 所示。...备胎 ---- 你再回头看下图 2 ,会发现二哥在图中从 tcp_bpf_sendmsg() 以及 tcp_bpf_recvmsg() 分别拉了一条虚线到 tcp_sendmsg() 和 tcp_recvmsg...我管 tcp_sendmsg() 和 tcp_recvmsg() 叫备胎。因为 tcp_bpf_sendmsg() 以及 tcp_bpf_recvmsg() 在处理一些异常情况时就直接走老路了。
领取专属 10元无门槛券
手把手带您无忧上云