Linux网络编程
Sandeldeng
这个作者很懒,什么都没留下…
展开
-
linux网络编程之socket(一):socket概述和字节序、地址转换函数
一、什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口。 socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信。 socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及以后要讲的UNIX Domain Socket。然而,各种网络协议的地址格式并不相同,如下图所示: IPv4和IPv6的地址转载 2016-10-22 12:21:55 · 442 阅读 · 0 评论 -
linux网络编程之socket(十五):UNIX域套接字编程和socketpair 函数
一、UNIX Domain Socket IPCsocket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和转载 2016-10-23 22:38:57 · 453 阅读 · 0 评论 -
linux网络编程之socket(十六):通过UNIX域套接字传递描述符和 sendmsg/recvmsg 函数
在前面我们介绍了UNIX域套接字编程,更重要的一点是UNIX域套接字可以在同一台主机上各进程之间传递文件描述符。 下面先来看两个函数:#include <sys/types.h>#include <sys/socket.h>ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);ssize_t recvmsg(int转载 2016-10-23 22:45:26 · 569 阅读 · 0 评论 -
linux网络编程之进程间通信基础(一):进程间通信概述
一、顺序程序与并发程序特征 顺序程序特征 顺序性 封闭性:(运行环境的封闭性) 确定性 可再现性 并发程序特征 共享性 并发性 随机性二、进程互斥 1、由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥 2、系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源。 3、在进程中涉及到互斥资源的程序段叫临界转载 2016-10-23 22:50:44 · 309 阅读 · 0 评论 -
linux网络编程之进程间通信基础(二):死锁、信号量与PV原语简介
一、死锁 (1) 死锁是指多个进程之间相互等待对方的资源,而在得到对方资源之前又不释放自己的资源,这样,造成循环等待的一种现象。如果所有进程都在等待一个不可能发生的事,则进程就死锁了。(2)死锁产生的必要条件: 互斥条件 进程对资源进行排它性使用,即在一段时间内某资源仅为一个进程所占用。 请求和保持条件 当进程因请求资源而阻塞时,对已获得的资源保持不放。 不可剥夺条件 进程已获得的转载 2016-10-24 08:33:01 · 619 阅读 · 0 评论 -
linux网络编程之System V 消息队列(一):消息队列内核结构和msgget、msgctl 函数
一、消息队列 1、消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 2、每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值 3、消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的,且消息队列的读取不一定是先入先出。 4、消息队列也有管道一样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGMN转载 2016-10-24 08:50:04 · 373 阅读 · 0 评论 -
linux网络编程之System V 消息队列(二):消息队列实现回射客户/服务器和 msgsnd、msgrcv 函数
一、msgsnd 和 msgrcv 函数 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>功能:把一条消息添加到消息队列中 原型 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数 msgid: 由msgget函数返回转载 2016-10-24 09:42:01 · 604 阅读 · 0 评论 -
linux网络编程之共享内存简介和mmap 函数
一、共享内存简介 共享内存区是最快的IPC形式,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。 即每个进程地址空间都有一个共享存储器的映射区,当这块区域都映射到相同的真正的物理地址空间时,可以通过这块区域进行数据交换,例如共享库就是这么实现的,很多进程都会使用同一个函数如printf,也许在真正的物理地址空间中只存在一份printf.o ,然转载 2016-10-24 09:58:38 · 364 阅读 · 0 评论 -
linux网络编程之System V 共享内存 和 系列函数
跟消息队列一样,共享内存也有自己的数据结构,如下:struct shmid_ds{ struct ipc_perm shm_perm; /* Ownership and permissions */ size_t shm_segsz; /* Size of segment (bytes) */ time_t shm_atime; /* La转载 2016-10-24 10:20:05 · 480 阅读 · 0 评论 -
linux网络编程之System V 信号量(一):封装一个信号量集操作函数的工具
信号量的概念参见这里。 与消息队列和共享内存一样,信号量集也有自己的数据结构:struct semid_ds{ struct ipc_perm sem_perm; /* Ownership and permissions */ time_t sem_otime; /* Last semop time */ time_t sem_cti转载 2016-10-24 10:30:47 · 934 阅读 · 0 评论 -
linux网络编程之System V 信号量(二):用信号量实现进程互斥示例和解决哲学家就餐问题
一、我们在前面讲进程间通信的时候提到过进程互斥的概念,下面写个程序来模拟一下,程序流程如下图: 即父进程打印字符O,子进程打印字符X,每次打印一个字符后要sleep 一下,这里要演示的效果是,在打印程序的边界有PV操作,故每个进程中间sleep 的时间即使时间片轮转到另一进程,由于资源不可用也不会穿插输出其他字符,也就是说O或者X字符都会是成对出现的,如OOXXOOOOXXXXXXOO….转载 2016-10-26 15:17:15 · 1232 阅读 · 0 评论 -
linux网络编程之socket(十四):基于UDP协议的网络程序
一、下图是典型的UDP客户端/服务器通讯过程 下面依照通信流程,我们来实现一个UDP回射客户/服务器 #include <sys/types.h>#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t sendto(int sockfd, const vo转载 2016-10-23 22:33:52 · 239 阅读 · 0 评论 -
linux网络编程之socket(十三):epoll 系列函数简介、与select、poll 的区别
一、epoll 系列函数简介#include <sys/epoll.h>int epoll_create(int size);int epoll_create1(int flags);int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);int epoll_wait(int epfd, struct epoll_转载 2016-10-23 22:22:12 · 473 阅读 · 0 评论 -
linux网络编程之socket(十二):select函数的并发限制和 poll 函数应用举例
一、用select实现的并发服务器,能达到的并发数,受两方面限制1、一个进程能打开的最大文件描述符限制。这可以通过调整内核参数。可以通过ulimit -n来调整或者使用setrlimit函数设置, 但一个系统所能打开的最大数也是有限的,跟内存大小有关,可以通过cat /proc/sys/fs/file-max 查看 2、select中的fd_set集合容量的限制(FD_SETSIZE,一般为102转载 2016-10-22 22:49:10 · 515 阅读 · 0 评论 -
linux网络编程之socket(二):C/S程序的一般流程和基本socket函数
一、基于TCP协议的网络程序 下图是基于TCP协议的客户端/服务器程序的一般流程: 服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务转载 2016-10-22 12:30:52 · 312 阅读 · 0 评论 -
linux网络编程之socket(七):一个进程发起多个连接和gethostbyname等函数
一、在前面讲过的最简单的回射客户/服务器程序中,一个客户端即一个进程,只会发起一个连接,只要稍微修改一下就可以让一个客户端发起多个连 接,然后只利用其中一个连接发送数据。先来认识一个函数getsockname #include <sys/socket.h> int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrle转载 2016-10-22 14:37:51 · 1427 阅读 · 0 评论 -
linux网络编程之socket(五):tcp流协议产生的粘包问题和解决方案
我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因。而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息转载 2016-10-22 12:49:48 · 492 阅读 · 0 评论 -
linux网络编程之socket(四):使用fork并发处理多个client的请求和对等通信p2p
一、在前面讲过的回射客户/服务器程序中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现。网络服务器通常用fork来同时服务多个客户端,父进程专门负责监听端口,每次accept一个新的客户端连接就fork出一个子进程专门服务这个客户端。但是子进程退出时会产生僵尸进程,父进程要注意处理SIGCHLD信转载 2016-10-22 12:45:25 · 1039 阅读 · 0 评论 -
linux网络编程之socket(三):最简单的回射客户/服务器程序、time_wait 状态
下面通过最简单的客户端/服务器程序的实例来学习socket API。 echoser.c 程序的功能是从客户端读取字符然后直接回射回去。/************************************************************************* > File Name: echoser.c > Author: Simba > Ma转载 2016-10-22 12:41:43 · 432 阅读 · 0 评论 -
linux网络编程之socket(六):利用recv和readn函数实现readline函数
在前面的文章中,我们为了避免粘包问题,实现了一个readn函数读取固定字节的数据。如果应用层协议的各字段长度固定,用readn来读是非常方便的。例如设计一种客户端上传文件的协议,规定前12字节表示文件名,超过12字节的文件名截断,不足12字节的文件名用’\0’补齐,从第13字节开始是文件内容,上传完所有文件内容后关闭连接,服务器可以先调用readn读12个字节,根据文件名创建文件,然后在一个循环中调转载 2016-10-22 12:53:20 · 837 阅读 · 0 评论 -
linux网络编程之socket(八):五种I/O模型和select函数简介
一、五种I/O模型 1、阻塞I/O 我们在前面所说的I/O模型都是阻塞I/O,即调用recv系统调用,如果没有数据则阻塞等待,当数据到来则将数据从内核空间(套接口缓冲区)拷贝到用户空间(recv函数提供的buf),然后recv返回,进行数据处理。2、非阻塞I/O 我们可以使用 fcntl(fd, F_SETFL, flag | O_NONBLOCK); 将套接字标志变成非阻塞,调用re转载 2016-10-22 17:51:03 · 391 阅读 · 0 评论 -
linux网络编程之socket(九):使用select函数改进客户端/服务器端程序
一、当我们使用单进程单连接且使用readline修改后的客户端程序,去连接使用readline修改后的服务器端程序,会出现一个有趣的现象,先来看输出: 先运行服务器端,再运行客户端, simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$ ./echoser_recv_peek recv connect ip=127.0.0.1转载 2016-10-22 20:42:04 · 437 阅读 · 0 评论 -
linux网络编程之socket(十):shutdown 与 close 函数 的区别
假设server和client 已经建立了连接,server调用了close, 发送FIN 段给client(其实不一定会发送FIN段,后面再说),此时server不能再通过socket发送和接收数据,此时client调用read,如果接收到FIN 段会返回0,但client此时还是可以write 给server的,write调用只负责把数据交给TCP发送缓冲区就可以成功返回了,所以不会出错,而se转载 2016-10-22 21:00:23 · 515 阅读 · 0 评论 -
linux网络编程之socket(十一):套接字I/O超时设置方法和用select实现超时
注:如无特殊说明,sockfd 原始状态都是阻塞的。一、使用alarm 函数设置超时void handler(int sig){}signal(SIGALRM, handler);alarm(5);int ret = read(fd, buf, sizeof(buf));if (ret == -1 && errno == EINTR) errno = ETIMEOUT;else转载 2016-10-22 21:47:22 · 1380 阅读 · 0 评论 -
linux网络编程之System V 信号量(三):基于生产者-消费者模型实现先进先出的共享内存段
生产者消费者问题:该问题描述了两个共享固定大小缓冲区的进程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。 我们可以用信号量解决生产者消费者问题,如下图: 定义3个信号量,sem_fu转载 2016-10-26 15:31:00 · 623 阅读 · 0 评论