socket编程TCP
1.创建套接字文件
第一个参数:底层用的ip报文统一使用的网络协议都是AFIN
第二个参数:面向字节流
流式套接
第三个参数:设置为0
成功时会得到一个文件描述符
当我们的代码调用socket创建套接字时,系统会分配当前最小的,未被使用的整数作为新的文件描述符,0,1,2 已经被标准输入,标准输出,标准错误占用,因此首次创建套接字时,会分配3作为文件描述符
2.bind众所周知的端口号
3.设置socket状态为listen,tcp特有的
TCP需要listen是因为TCP是面向连接的协议,必须先在发送方和接收方之间建立一条可靠的连接。listen函数使服务器的套接字进入被动监听状态,准备接收客户端的连接请求
只要tcp服务器处于listen状态,它就已经可以被连接了
有两个连接成功是因为:tcp是全双工的,客户端和服务器在一台机器上
客户端到服务器的连接,服务器到客户端的连接
获取链接accept
获取连接才能进行通信操作
服务器用accept接受连接
返回值,为什么还是文件描述符,这里的文件描述符和socket的返回的文件描述符?
我们可以举个例子,小王是一家店的店员,工作是在店外拉客,负责获取链接 listensockf(监听套接字的文件描述符);店内有其他店员,工作就是服务,accept返回值,就是给我们提供服务,读写,即IO服务
调用 read 函数成功时,返回值是实际读取到的字节数
connect
客户端需要调用connect()连接服务器
connect和bind的参数一致
参数是对方的地址即目标服务器的socket地址
客户端会在connect成功之后在底层自动进行bind
参数是自己的地址
1. 进程如果退出了,曾经打开的文件默认会被自动释放,fd会被自动关闭
2. 如果进程打开了一个文件,得到了一个fd,如果再创建子进程,这个子进程可以拿到父进程的fd进行访问 eg:管道
有多个客户端和服务器建立链接的时候,我们把服务器叉掉服务器箱立即重启就会绑定失败,启动不了会进行频繁的更换端口号
1. 如果进程打开了一个文件,得到了一个fd,这个fd线程能看到
2. 线程不敢关闭自己不需要的fd,因为文件描述服是共享的,不能把不需要的关掉
popen
打开一个管道,创建子进程,执行指定的shell命令(command参数)
返回与该管道关联的文件流指针
type指向管道方向: r 输出 w输入
父进程创建管道(包含读端和写端两个文件描述符)再创建子进程,由子进程exce执行命令,执行对应的命令时,会把子进程的标准输出重定向到管道的写端,执行完命令后把结果写到管道里,父进程以文件的形式来读取结果
长服务和短服务
长服务:启动后长期运行,除非主动停止,崩溃或系统重启否则持续提供服务的进程。多进程多线程比较合适
短服务:为完成特定任务而启动,任务结束后立即终止的进程,生命周期短暂。
线程池更适合处理短服务