linux 环境网络编程
主要分tcp/ip基础,socket编程,进程间通信(信号量,共享内存,消息队列等),线程四大类来讲。
代码已经分类上传至 https://github.com/JnuSimba/UNP。
s1mba
这个作者很懒,什么都没留下…
展开
-
《TCP/IP 卷一》笔记、ping和traceroute 的实现思路
一、TCP协议相关笔记Normally TCP does not send an ACK the instant it receives data. Instead, it delays the ACK, hoping to have data going in the same direction as the ACK, so the ACK can be sent along原创 2013-10-21 20:59:57 · 4344 阅读 · 2 评论 -
浅谈原始套接字 SOCK_RAW 的内幕及其应用(port scan, packet sniffer, syn flood, icmp flood)
一、SOCK_RAW 内幕首先在讲SOCK_RAW 之前,先来看创建socket 的函数:int socket(int domain, int type, int protocol);domain :指定通信协议族(protocol family/address) C++ Code 123456789101原创 2013-10-07 16:30:55 · 29321 阅读 · 1 评论 -
socket 请求接收完整的一个http响应(设置recv 接收超时选项SO_RCVTIMEO)
在前面的系列网络编程文章中,我们都是使用socket 自己实现客户端和服务器端来互相发数据测试,现在尝试使用socket 客户端发送http 请求给某个网站,然后接收网站的响应数据。http 协议参考 这里。代码如下: C++ Code 1234567891011121314151617原创 2013-10-06 20:26:54 · 11784 阅读 · 1 评论 -
linux网络编程之posix 线程(四):posix 条件变量与互斥锁 示例生产者--消费者问题
一、posix 条件变量一种线程间同步的情形:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行。在pthread库中通过条件变量(Condition Variable)来阻塞等待一个条件,或者唤醒等待这个条件的线程。Condition Variable用pthread_cond_t类型的变量表原创 2013-06-19 17:02:18 · 6891 阅读 · 11 评论 -
linux网络编程之posix 线程(三):posix 匿名信号量与互斥锁 示例生产者--消费者问题
一、posix 信号量信号量的概念参见这里。前面也讲过system v 信号量,现在来说说posix 信号量。system v 信号量只能用于进程间同步,而posix 信号量除了可以进程间同步,还可以线程间同步。system v 信号量每次PV操作可以是N,但Posix 信号量每次PV只能是1。除此之外,posix 信号量还有命名和匿名之分(man 7 sem_overview):原创 2013-06-18 13:39:15 · 5544 阅读 · 6 评论 -
linux网络编程之posix 线程(二):线程的属性和 线程特定数据 Thread-specific Data
一、posix 线程属性POSIX 线程库定义了线程属性对象 pthread_attr_t ,它封装了线程的创建者可以访问和修改的线程属性。主要包括如下属性:1. 作用域(scope)2. 栈尺寸(stack size)3. 栈地址(stack address)4. 优先级(priority)5. 分离的状态(detached state)6. 调度策略和参数(sc原创 2013-06-16 22:54:33 · 4280 阅读 · 0 评论 -
linux网络编程之posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序
一、posix 线程概述我们知道,进程在各自独立的地址空间中运行,进程之间共享数据需要用进程间通信机制,有些情况需要在一个进程中同时执行多个控制流程,这时候线程就派上了用场,比如实现一个图形界面的下载软件,一方面需要和用户交互,等待和处理用户的鼠标键盘事件,另一方面又需要同时下载多个文件,等待和处理从多个网络主机发来的数据,这些任务都需要一个“等待-处理”的循环,可以用多线程实现,一个线程专门原创 2013-06-16 19:08:13 · 9890 阅读 · 2 评论 -
linux网络编程之POSIX 共享内存和 系列函数
在前面介绍了system v 共享内存的相关知识,现在来稍微看看posix 共享内存 和系列函数。共享内存简单来说就是一块真正的物理内存区域,可以使用一些函数将这块区域映射到进程的地址空间进行读写,而posix 共享内存与system v 共享内存不同的是它是用虚拟文件系统(tmpfs)实现的,已经挂载在/dev/shm 下面。man 7 shm_overview下面来看系列函数,原创 2013-06-16 15:11:27 · 4767 阅读 · 0 评论 -
linux网络编程之POSIX 消息队列 和 系列函数
一、在前面介绍了system v 消息队列的相关知识,现在来稍微看看posix 消息队列。其实消息队列就是一个可以让进程间交换数据的场所,而两个标准的消息队列最大的不同可能只是api 函数的不同,如system v 的系列函数是msgxxx,而posix 是mq_xxx。posix 消息队列也有一些对消息长度等的限制,man 7 mq_overview:simba@ubuntu:~/Doc原创 2013-06-16 10:54:26 · 6726 阅读 · 5 评论 -
linux网络编程之System V 信号量(三):基于生产者-消费者模型实现先进先出的共享内存段
生产者消费者问题:该问题描述了两个共享固定大小缓冲区的进程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。我们可以用信号量解决生产者消费者问题,如下图:定义3个信号量,s原创 2013-06-15 22:35:54 · 6745 阅读 · 2 评论 -
linux网络编程之System V 信号量(二):用信号量实现进程互斥示例和解决哲学家就餐问题
一、我们在前面讲进程间通信的时候提到过进程互斥的概念,下面写个程序来模拟一下,程序流程如下图:即父进程打印字符O,子进程打印字符X,每次打印一个字符后要sleep 一下,这里要演示的效果是,在打印程序的边界有PV操作,故每个进程中间sleep 的时间即使时间片轮转到另一进程,由于资源不可用也不会穿插输出其他字符,也就是说O或者X字符都会是成对出现的,如OOXXOOOOXXXXXXOO.原创 2013-06-15 16:57:13 · 5058 阅读 · 1 评论 -
linux网络编程之System V 信号量(一):封装一个信号量集操作函数的工具
信号量的概念参见这里。与消息队列和共享内存一样,信号量集也有自己的数据结构:struct semid_ds {struct ipc_perm sem_perm; /* Ownership and permissions */time_t sem_otime; /* Last semop time */time_t sem_ctime; /* Last原创 2013-06-15 11:12:10 · 5691 阅读 · 1 评论 -
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; /* Last a原创 2013-06-14 22:49:44 · 4059 阅读 · 0 评论 -
linux网络编程之共享内存简介和mmap 函数
一、共享内存简介共享内存区是最快的IPC形式,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。即每个进程地址空间都有一个共享存储器的映射区,当这块区域都映射到相同的真正的物理地址空间时,可以通过这块区域进行数据交换,例如共享库就是这么实现的,很多进程都会使用同一个函数如printf,也许在真正的物理地址空间中只存在一份printf原创 2013-06-14 20:11:02 · 6920 阅读 · 1 评论 -
linux网络编程之System V 消息队列(二):消息队列实现回射客户/服务器和 msgsnd、msgrcv 函数
一、msgsnd 和 msgrcv 函数 #include #include #include 功能:把一条消息添加到消息队列中原型 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);参数msgid: 由msgget函数返回的消息队列标识码msgp:是一个指针,指针指向准原创 2013-06-14 17:05:14 · 4734 阅读 · 0 评论 -
linux网络编程之System V 消息队列(一):消息队列内核结构和msgget、msgctl 函数
一、消息队列1、消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法2、每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值3、消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的,且消息队列的读取不一定是先入先出。4、消息队列也有管道一样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGM原创 2013-06-13 21:09:48 · 5724 阅读 · 3 评论 -
linux网络编程之进程间通信基础(二):死锁、信号量与PV原语简介
一、死锁(1) 死锁是指多个进程之间相互等待对方的资源,而在得到对方资源之前又不释放自己的资源,这样,造成循环等待的一种现象。如果所有进程都在等待一个不可能发生的事,则进程就死锁了。(2)死锁产生的必要条件:互斥条件进程对资源进行排它性使用,即在一段时间内某资源仅为一个进程所占用。 请求和保持条件当进程因请求资源而阻塞时,对已获得的资源保持不放。原创 2013-06-13 18:16:21 · 7937 阅读 · 1 评论 -
linux网络编程之进程间通信基础(一):进程间通信概述
一、顺序程序与并发程序特征顺序程序特征顺序性封闭性:(运行环境的封闭性)确定性可再现性并发程序特征共享性并发性随机性二、进程互斥1、由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥2、系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源。3原创 2013-06-13 15:35:24 · 5107 阅读 · 0 评论 -
linux网络编程之socket(十六):通过UNIX域套接字传递描述符和 sendmsg/recvmsg 函数
在前面我们介绍了UNIX域套接字编程,更重要的一点是UNIX域套接字可以在同一台主机上各进程之间传递文件描述符。下面先来看两个函数: #include #include ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);ssize_t recvmsg(int sockfd, struct ms原创 2013-06-12 19:10:56 · 11697 阅读 · 4 评论 -
linux网络编程之socket(十五):UNIX域套接字编程和socketpair 函数
一、UNIX Domain Socket IPCsocket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、原创 2013-06-12 16:19:23 · 15547 阅读 · 1 评论 -
linux网络编程之socket(十四):基于UDP协议的网络程序
一、下图是典型的UDP客户端/服务器通讯过程下面依照通信流程,我们来实现一个UDP回射客户/服务器 #include #include ssize_t send(int sockfd, const void *buf, size_t len, int flags); ssize_t sendto(int sockfd, const void *bu原创 2013-06-12 09:03:05 · 30291 阅读 · 16 评论 -
linux网络编程之socket(十三):epoll 系列函数简介、与select、poll 的区别
一、epoll 系列函数简介#include 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_event原创 2013-06-11 19:24:22 · 12263 阅读 · 7 评论 -
linux网络编程之socket(十二):select函数的并发限制和 poll 函数应用举例
一、用select实现的并发服务器,能达到的并发数,受两方面限制1、一个进程能打开的最大文件描述符限制。这可以通过调整内核参数。可以通过ulimit -n来调整或者使用setrlimit函数设置, 但一个系统所能打开的最大数也是有限的,跟内存大小有关,可以通过cat /proc/sys/fs/file-max 查看2、select中的fd_set集合容量的限制(FD_SETSI原创 2013-06-11 15:12:41 · 7390 阅读 · 4 评论 -
linux网络编程之socket(十一):套接字I/O超时设置方法和用select实现超时
一、使用alarm 函数设置超时 C++ Code 12345678910111213void handler(int sig){}signal(SIGALRM, handler);alarm(5);int ret = read(fd, buf, sizeof(b原创 2013-06-11 10:36:17 · 8732 阅读 · 2 评论 -
linux网络编程之socket(十):shutdown 与 close 函数 的区别
假设server和client 已经建立了连接,server调用了close, 发送FIN 段给client(其实不一定会发送FIN段,后面再说),此时server不能再通过socket发送和接收数据,此时client调用read,如果接收到FIN 段会返回0,但client此时还是可以write 给server的,write调用只负责把数据交给TCP发送缓冲区就可以成功返回了,所以不会出错,而s原创 2013-06-10 22:03:20 · 24134 阅读 · 5 评论 -
linux网络编程之socket(九):使用select函数改进客户端/服务器端程序
一、当我们使用单进程单连接且使用readline修改后的客户端程序,去连接使用readline修改后的服务器端程序,会出现一个有趣的现象,先来看输出:先运行服务器端,再运行客户端,simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$ ./echoser_recv_peek recv connect ip=127.0.0.原创 2013-06-10 19:45:45 · 20209 阅读 · 14 评论 -
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); 将套接原创 2013-06-10 15:35:53 · 8989 阅读 · 0 评论 -
linux网络编程之socket(七):一个进程发起多个连接和gethostbyname等函数
一、在前面讲过的最简单的回射客户/服务器程序中,一个客户端即一个进程,只会发起一个连接,只要稍微修改一下就可以让一个客户端发起多个连接,然后只利用其中一个连接发送数据。先来认识一个函数getsockname #include int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);利用此原创 2013-06-09 12:05:36 · 5736 阅读 · 0 评论 -
linux网络编程之socket(六):利用recv和readn函数实现readline函数
在前面的文章中,我们为了避免粘包问题,实现了一个readn函数读取固定字节的数据。如果应用层协议的各字段长度固定,用readn来读是非常方便的。例如设计一种客户端上传文件的协议,规定前12字节表示文件名,超过12字节的文件名截断,不足12字节的文件名用'\0'补齐,从第13字节开始是文件内容,上传完所有文件内容后关闭连接,服务器可以先调用readn读12个字节,根据文件名创建文件,然后在一个循环中原创 2013-06-08 21:19:58 · 9206 阅读 · 0 评论 -
linux网络编程之socket(五):tcp流协议产生的粘包问题和解决方案
我们在前面曾经说过,发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),在底层通讯中这些数据可能被拆成很多数据包来发送,但是一个数据包有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因。而UDP是面向原创 2013-06-06 23:52:38 · 11766 阅读 · 11 评论 -
linux网络编程之socket(四):使用fork并发处理多个client的请求和对等通信p2p
一、在前面讲过的回射客户/服务器程序中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现。网络服务器通常用fork来同时服务多个客户端,父进程专门负责监听端口,每次accept一个新的客户端连接就fork出一个子进程专门服务这个客户端。但是子进程退出时会产生僵尸进程,父进程要注意处理SIGCHLD原创 2013-06-05 22:28:32 · 24234 阅读 · 5 评论 -
linux网络编程之socket(三):最简单的回射客户/服务器程序、time_wait 状态
下面通过最简单的客户端/服务器程序的实例来学习socket API。echoser.c 程序的功能是从客户端读取字符然后直接回射回去。 C++ Code 123456789101112131415161718192021222324252627原创 2013-06-05 09:31:37 · 9427 阅读 · 5 评论 -
linux网络编程之socket(二):C/S程序的一般流程和基本socket函数
一、基于TCP协议的网络程序下图是基于TCP协议的客户端/服务器程序的一般流程:服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个AC原创 2013-06-04 19:54:03 · 14942 阅读 · 2 评论 -
linux网络编程之socket(一):socket概述和字节序、地址转换函数
一、什么是socketsocket可以看成是用户进程与内核网络协议栈的编程接口。socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信。socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及以后要讲的UNIX Domain Socket。然而,各种网络协议的地址格式并不相同,如下图所示:IPv原创 2013-06-03 14:17:33 · 9659 阅读 · 2 评论 -
linux网络编程之TCP/IP基础(五):分析一帧基于UDP的TFTP协议帧
下图是UDP的段格式:相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度。下面分析一帧基于UDP的TFTP协议帧:以太网首部0000: 00 05 5d 67 d0 b1 00 05 5d 61 58 a8 08 00 IP首部0000: 45 000010: 00 53 93 25 00 00原创 2013-05-24 11:16:01 · 5696 阅读 · 0 评论 -
linux网络编程之TCP/IP基础(四):TCP连接的建立和断开、滑动窗口
一、TCP段格式:TCP的段格式如下图所示源端口号与目的端口号源端口号和目的端口号,加上IP首部的源IP地址和目的IP地址唯一确定一个TCP连接。序号序号表示在这个报文段中的第一个数据字节序号。确认号仅当ACK标志为1时有效。确认号表示期望收到的下一个字节的序号。头部长度4位,TCP头部最多60个字节,最少20个字节保留位6位原创 2013-05-23 22:02:41 · 7499 阅读 · 2 评论 -
linux网络编程之TCP/IP基础(三):IP数据报格式和IP地址路由
一、IP数据报格式IP数据报格式如下:版本IP协议版本号,长度为4位,IPv4此字段值为4,IPv6此字段值为6首部长度以32位的字为单位,该字段长度为4位,最小值为5,即不带任何选项的IP首部20个字节;最大值为15,所以首部长度最大为60个字节服务类型(TOS)长度为8位。此字段包含3位的优先权(现已忽略),4位的服务类型子字段和1位的保留位(必须置原创 2013-05-23 12:27:00 · 7421 阅读 · 3 评论 -
linux网络编程之TCP/IP基础(二):利用ARP和ICMP协议解释ping命令
一、MTU以太网和IEEE 802.3对数据帧的长度都有限制,其最大值分别是1500和1492字节,将这个限制称作最大传输单元(MTU,Maximum Transmission Unit)如果IP层有一个数据报要传,而且数据的长度比链路层的MTU还大,那么IP层就要进行分片(Fragmentation),把数据报分成若干片,这样每一片都小于MTU。当网络上的两台主机互相进行通信时,两台原创 2013-05-22 21:39:17 · 13140 阅读 · 6 评论 -
linux网络编程之TCP/IP基础(一):TCP/IP协议栈与数据报封装
一、ISO/OSI参考模型OSI(open system interconnection)开放系统互联模型是由ISO(International Organization for Standardization)国际标准化组织定义的网络分层模型,共七层,如下图。物理层(Physical Layer):物理层定义了所有电子及物理设备的规范,为上层的传输提供了一个物理介质,本层中数原创 2013-05-21 20:57:18 · 17326 阅读 · 8 评论