回顾:
信号量集 - 如何使用信号量集实现 控制访问共享资源的并行进程最大数量。信号量集的使用步骤:
1 ftok() 获取 key
2 semget() 创建/获取 信号量集(数组)
3 给每个信号量做初始化最大值 函数semctl()
4 对信号量的计数进行 +1 或 -1 操作 函数semop
5 如果不再使用,可以删除 semctl
网络 - 网络常识 (IP地址/端口)
socket编程
一对一 : 本地通信和网络通信
本地通信的通信地址:sockaddr_un,通信媒介是socket文件。
网络通信的通信地址:sockaddr_in。
步骤:
1 socket函数,返回 socket描述符
2 准备通信地址
3 bind/connect
4 read/write
5 close()
今天:
TCP和UDP的区别:
TCP 传输数据时,采用的是 数据流方式。
UDP 传输数据时,采用的是 数据报方式。
TCP 是有连接协议(基于连接),在数据传输的整个过程,保持服务器和客户端的连接。会 重发 一切错误数据,因此 可以保证 数据的正确性和完整性。
UDP 是无连接协议,在数据发送和接收的时候连一下即可,发送/接收完毕就不保持连接。不会 重复错误数据,因此 UDP有可能丢失数据。
一对多模型
TCP的编程步骤:
服务端:
1 socket() 获得一个sockfd。注意第二个参数必须SOCK_STREAM.
2 准备通信地址(必须服务器的)
3 bind()绑定。(开放了端口,允许客户端连接)
4 监听客户端 listen()函数
5 等待客户端的连接 accept(),返回 用于交互的 socket描述符。
6 使用第5步返回sock描述符 进行读写通信。
7 关闭sockfd。
客户端的代码与一对一 一样。注意第二个参数必须SOCK_STREAM
TCP一对多模型,有两类描述符:
第一步的描述符不再参与信息交互,只是等待客户端的连接(accept)
accept()在客户端连接上来后,会返回一个新的描述符,用于读写通信。
练习:
1 在客户端加上输入功能,允许发送不同的信息,并且客户端和服务器端代码 要支持 多次输入和输出(读写上加循环),输入bye退出。
客户端发送的内存改为输入,服务器发回给客户端的内容改成客户端输入。
2 可以考虑在 服务器端启动多进程fork(),支持多个客户端的并行。
UDP编程:
UDP开发没有listen()和accept(),发送和接收函数使用:sendto() / recvfrom() ,个别时候可以使用read(),write()基本不能使用。
sendto() 相当于 write()+connect()效果,参数是前3个参数和write()一样,第4个参数置0即可,后两个参数和connect()一样。区别:sendto()只是发送时连一下,不会保持连接。而connect()保持连接。
recvfrom() 相当于 read()+accept()效果,参数前3个和read()一样,第4个参数置0即可,后两个参数和accept()一样。
线程
网络一般都需要实现代码的并行,代码的并行必须借助多进程/多线程。
进程和线程的概念
主流操作系统中都是支持多进程,而在每个进程的内部,都支持多线程并行。
进程,重量级的,拥有自己独立的内存空间。
线程,轻量级的,不需要拥有自己独立的内存空间,只是额外拥有一个独立的栈。一个进程内存的所有线程共享进程的资源(代码区、全局区、堆、文件目录....) 。
因此网络开发经常是 网络+多线程 模式。
进程中支持多线程并行,其中有一个是主线程,进程中必须有主线程(main函数)。
校渲杏幸桓鍪侵飨叱蹋讨斜匦胗兄飨叱?main函数)。