![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
网络编程
zhjs_abc
不要在可以吃苦的时候而选择了安逸
展开
-
TCP/IP网络编程学习笔记(十三)
IO完成端口模型的实现要点:创建一个具有重叠(Overlapped)属性的socket(可以用WSASocket()来创建);创建一个IO完成端口对象(简称CP对象)句柄(使用CreateIOCompletionPort()创建);创建多个线程(比如可以创建线程池),并将上述CP对象句柄传递给创建的线程(作为线程函数的参数传递进去,CP对象将通过该句柄分配到线程)。然后,在线程中调用GetQueuedCompletionStatus()进行阻塞(注意,结束时一定要主动关闭线程句柄或者使用对应的..原创 2020-09-26 13:06:20 · 115 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(十二)
重叠IO模型(Overlapped IO)中,IO操作本身是异步的,与调用IO函数的线程无关。也就是说,调用IO的线程只是发起IO操作,IO操作本身是由其他线程完成的,调用IO的线程可以同时干其他事情。不过,当确认IO操作是否完成时,默认还是需要调用IO的线程来确认。如果添加了回调函数,也就是IO操作完成后自动执行一个后处理函数,此时这个后处理函数也是由刚才发起IO请求的线程来执行的,并且只有当发起IO请求的线程执行了等待函数(比如WaitForSingleObjectEx(),WaitForMulti..原创 2020-09-23 15:52:03 · 87 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(十一)
Windows下类似与Linux下的epoll异步通知IO模型(不是异步IO模型)是基于WSAEventSelect实现的(还有一种WSAAsyncSelect也能实现,不过一般用于UI);WSAEventSelect实现的异步IO通知模型的过程:使用WSACreateEvent()创建一个手动重置事件(注意结束时要用WSACloseEvent()来销毁这个手动重置事件);使用WSAEventSelect()将一个句柄(比如socket句柄)与上一步创建的手动重置事件进行绑定,调用此函数时..原创 2020-09-22 15:55:54 · 88 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(十)
Linux下如果想使用线程安全的标准库函数,则要么在头文件上方定义一个枚举类型:#define _REENTRANT // 表示可重入#include <...>要么在编译的时候添加宏-D_REENTRANT:gcc -D_REENTRANT test.c -o test -lpthread详情请看:LINUX C编程中_REENTRANT宏的作用;注意,Linux下编写多线程程序在编译时最好都加上宏-D_REENTRANT;不管是信号量还是互斥体,在使用前都要in..原创 2020-09-19 19:20:51 · 244 阅读 · 0 评论 -
epoll比select高效的原因
select每次调用select()时都要传入fds数组,而epoll在内核维护了一个等待队列,每次调用epoll_wait()时不需要传入等待队列进去,只在执行epoll_ctl()时才更新等待队列。降低了内核与用户层的数据迁移;select()返回后每次都要遍历所有被监视的文件描述符,而epoll_wait()返回时已经将有事件发生的文件描述符放到了一个数组中,所以用户层只需要遍历有事件发生的文件描述符即可,大大降低了遍历范围;select是将当前进程添加到每个被监视的socket的等待队列里面,.原创 2020-09-18 14:34:27 · 234 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(九)
epoll模型的实现过程:使用epoll_create()在内核中创建一个epoll例程;将要监视的socket文件描述符存放到一个epoll_event结构体中,并设定要监视此文件描述符的哪种事件(如EPOLLIN事件,表示有数据进来时就唤醒进程);将上述设置好的epoll_event结构体通过epoll_ctl()函数注册到第一步创建的epoll例程中;在堆空间创建一个epoll_event动态数组,用于返回当前被触发的文件描述符相关信息;使用epoll_wait(),并传入上述创建的..原创 2020-09-18 14:31:59 · 107 阅读 · 0 评论 -
网络编程中select方法效率低的原因
当select同时监视多个socket时,内核会把本进程放到所有监视的socket中的等待队列里面。当某个socket有数据时,就会先把本进程从所有被监视的socket的等待队列中删除,并添加到工作队列里面。因此,每次调用select,都会进行遍历的添加和移除操作,很浪费时间;即使知道有socket可以访问数据了,但是用户态并不知道是哪个socket准备好了,还需要用户态逐一遍历所有被监视的socket,找出准备好的socket;最后,每次调用select时,还需要将整个fds数组传递到内核态,结束后.原创 2020-09-17 16:32:28 · 405 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(八)
使用fdopen()可以将文件描述符转成C的FILE指针,然后就可以通过标准的C的IO函数,如fread()、fputs()等实现高效的IO操作,不过要注意,对socket对应的FILE指针进行输出操作后,一定要刷新缓冲区(如可以使用fflush()来刷新),不然这些数据还在IO缓冲区中,并没有转移到socket缓冲区中,导致网络传输可能被延迟。此外,也可以使用fileno()函数将FILE文件指针转成文件描述符;使用fdopen()可以对同一个文件描述符创建多个不同作用的IO流,如可以创建一个读..原创 2020-09-17 14:49:51 · 82 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(七)
多播的Sender端就类似与客户端,Receiver端就类似与服务端;多播的实现过程:Sender端设置TTL;Sender端向一个D类IP地址发送UDP数据报(此IP地址可以随便指定一个类的即可);Receiver端将本次使用的socket所对应的本主机IP(可以用INADDR_ANY)存放于一个iq_mreq结构体中,并将一个与Sender端一致的D类IP也存放于上述结构体中;将上述设置好地址的结构体注册到多播组中;Receiver端设置本次使用的socket所对应的本主机IP(..原创 2020-09-16 15:58:29 · 112 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(六)
对于send()和recv()函数,其最后一个参数可以指定特别信息。使用MSG_OOB时表示传输紧急数据,但是只能传输一个字节数据。严格来说是接收端只能接收一个字节的紧急数据,其他数据还是按照正常的方式被接收。MSG_OOB在发送端很简单,直接用。在接收端,需要使用信号来配合使用,因为接收端会收到SIGURG的信号,需要注册信号处理函数,并在信号处理函数里面使用recv()并搭配MSG_OOB来读取一个字节的紧急信息。此外MSG_OOB并不会使这一个字节的数据传输的更快,它仍然按照TCP的顺序传输要求来传.原创 2020-09-15 21:52:13 · 115 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(五)
select()函数解析:int select(int maxfd, fd_set* readset, fd_set* writeset, fd_set* exceptset, const struct timeval* timeout);select()函数使用步骤:设置文件描述符;指定监视范围;设置超时;调用select()函数;查看调用结果。设置文件描述符时,直接使用FD_SET()将文件描述符对应的数值设置进fd_set结构体中即可;传给select()函数的第一..原创 2020-09-15 17:41:12 · 85 阅读 · 0 评论 -
TCP\IP网络编程学习笔记(四)
通过fork函数创建的子进程能够继承父进程中所有变量的值,但是一旦创建后,父进程和子进程中的变量不再有任何关系,即使是一个全局变量,父进程和子进程都会有不同的副本,修改并不会影响另一个进程中的这个全局变量的值;产生僵尸进程的原因:子进程使用exit()函数返回一个返回码(即exit()函数里面传入了实参);子进程main函数(每个进程最后都会从main函数正常返回的啦)通过return语句返回一个值。其根本原因是上述两种情况都会将返回的值传给操作系统,而操作系统不会销毁子进程,直到把..原创 2020-09-15 10:36:39 · 78 阅读 · 0 评论 -
TCP/IP网络编学习笔记(三)
可以设置TCP或UDP通信的输入缓冲大小和输出缓冲大小,但是最终大小并不一定是你所设定的大小;如果服务端先close,或者说先发出FIN消息表示分手,则服务端断开连接后,在短时间内无法再次bind相同的端口,因为上一次绑定此端口的socket处于time-wait过程中,还未被销毁(不过此时客户端是没有time-wait过程的,客户端一旦收到最后服务端发来的FIN消息后,就立即销毁对应的socket了)。所以你就会发现,服务端强制退出程序或者Ctrl+C后,立即重新运行服务端会出错,要等几分钟才行。这就.原创 2020-09-12 13:52:07 · 80 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(二)
TCP套接字在传输数据之前已经把对方的地址信息存储起来了,传输数据的时候就不再需要加上地址信息了。UDP套接字是无连接的,每次传输数据时候,都需要给出对方的地址信息;TCP套接字是一一对应的,一个TCP套接字只能和另一个TCP套接字连接。UDP套接字是一对多的,客户端和服务端都只需要一个UDP套接字。一个UDP套接字可以和其他任何一个UDP套接字通信;所有的套接字都需要分配IP地址和端口号。在TCP应用中,服务端通过bind()函数来给监听套接字分配IP和端口,客户端通过connect()函..原创 2020-09-11 20:39:45 · 176 阅读 · 0 评论 -
TCP/IP网络编程学习笔记(一)
IP层本身是面向消息的、不可靠的协议,每次传输数据时会帮我们选择路径,但并不一定一致。如果传输中发生路径错误,则选择其他路径;但是如果发生数据丢失或错误,则无法解决。因此,IP协议无法应对数据错误。IP层只关注一个数据包,数据包的传输顺序也是无法保证的;只有当服务端调用了listen()函数后(即创建了两个连接队列后),客户端才能发起连接请求(即此时客户端才能调用connect()函数,若提前调用将发生错误);服务端通过socket()函数创建的套接字并不是用于与客户端进行最终数据沟通的,此套接字是专.原创 2020-09-09 18:56:49 · 114 阅读 · 0 评论