socket:

为了执行网络I/O,一个进程做的第一件事就是调用socket函数。

family指明协议族,type指明类型,除非在原始套接口,protocol一般为0,并非所有的family,type组合都是有效的。

socket函数在成功时返回一个小的非负整数值,称为套接口描述字。

connect:

客户在调用函数connect前不必非得调用bind,必要时,内核会选择ip地址和临时端口。

TCP套接口,connect会激活三路握手,成功或者出错时返回。

几种错误:

1、TCP客户未收到SYN分节响应,返回ETIMEDOUT。

2、服务器无服务等待链接,返回ECONNREFUSED。

3、客户发出的SYN分节在中间路由器引发目的不可达ICMP错误,返回EHOSTENREACH或ENETUNREACH错误。

bind:

给套接口分配一个本地协议地址。

对于TCP,bind可以指定端口号,可以指定ip地址,可以都指定,也可以都不指定。

若让内核为套接口选择一个临时端口,函数bind不返回所选的值,必须调用getsockname来返回协议地址。

listen:

当函数socket创建一个套接口时,他被假设为主动套接口,listen将未使用的套接口变为被动套接口,告诉内核,此套接口可以接受连接请求。

内核要维护两个队列,两队列之和不超过backlog:

1、未完成连接队列,已有客户发出并到达服务端,服务端等待完成三路握手,SYN_RCVD。

2、已完成连接队列,已完成三路握手,ESTABLISHED。

Berkeley为backlog增加模糊因子,1.5,即最大可支持值*1.5。

不要把backlog定义为0,因为不同实现有不同的解释。

当一个客户SYN到达时,若队列是满的,则TCP忽略该分节,但是不发RST,客户会重发该分节。

套接字接收缓存区存储握手完成但未accept时到达的数据。

accept:

由TCP服务器调用,用于从已完成连接队列队头返回下一个已完成连接,已完成连接为空,进程进入睡眠。

accept的第三个参数addrlen是值-结果参数,传入套接口地址结构长度,返回内核存放在该套接字地址结构内的确切字节数。

accept会返回一个内核生成的全新的描述符,代表所返回客户的TCP连接,accept第一个参数称为监听套接字描述符,返回的为已连接套接字描述符,一个服务器一般只有一个监听套接字描述符,但有很多已连接套接字描述符,它随客户连接创建,随服务结束关闭。

fork和exec:

# include <unisted.h>

pid_t fork(void);

fork调用一次返回两次,父进程返回子进程的ID号,子进程返回0。

父进程fork前打开的描述符在fork返回后由子进程共享。

fork典型用法:

1、创建自身进程的副本。

2、一个进程执行另一个程序,先创建自身副本,然后副本调用exec将自身替换为新程序。

exec:

# include <unistd.h>

int execl(const char *pathname, const char *arg0, ... /* (char *) 0 */);

int execv(const char *pathname, char *const *argv[]);

int execle(const char *pathname, const char *arg0, ... /* (char *) 0 , char *const envp[] */);

int execve(const char *pathname, char *const *argv[], char *const envp[]);

int execlp(const char *filename, const char *arg0, ... /* (char *) 0 */);

int execvp(const char *filename, char *const *argv[]);

进程调用exec前打开的描述符通常跨exec继续保持打开,但可以使用fcntl设置FD_CLOEXEC描述符标志禁止掉。

并发服务器:

连接建立,accept返回,服务器调用fork,然后由子进程服务客户,父进程关闭已连接套接字,因为每个文件或套接字都有引用计数器子进程会将其加1,父进程关闭不会导致计数器为0,所以父进程关闭子进程不会终止客户连接。父进程关闭已连接套接字后,就可以继续等待下一次连接了。

close:

close一个TCP套接字的默认行为是把该套接字标记为已关闭,然后立即返回调用进程,该套接字描述符不能再由调用进程使用,但TCP仍然会尝试发送已排队等待发送到对端的任何数据,发送完毕后发正常TCP终止序列。

getsockname和getpeername

getsockname返回某个套接字关联的本地地址;

# include <sys/socket.h>

int getsocketname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);

1、在未调用bind的TCP客户上,connect成功返回,getsockname返回内核赋予该链接的本地IP地址和本地端口号。

2、调用bind端口号为0,返回内核赋予的本地端口号。

3、获取某套接字地址族。

4、返回已通配地址bind的TCP服务的地址。

getpeername返回某个套接字关联的外地协议地址;

# include <sys/socket.h>

int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);

当一个服务器是由调用过accept的某进程通过exec执行程序时,可以通过getpeername获取客户身份。

UNIX网络编程总结四的更多相关文章

  1. 【UNIX网络编程(四)】TCP套接字编程具体分析

    引言: 套接字编程事实上跟进程间通信有一定的相似性,可能也正由于此.stevens这位大神才会将套接字编程与进程间的通信都归为"网络编程",并分别写成了两本书<UNP1> ...

  2. unix网络编程第四章----基于TCP套接字编程

    为了执行网络I/O操作.进程必须做的第一件事情就是调用Socket函数.指定期待的通信协议 #include<sys/socket.h> int socket(int family,int ...

  3. 【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)

    RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [ ...

  4. [转载] 读《UNIX网络编程 卷1:套接字联网API》

    原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...

  5. UNIX网络编程——原始套接字的魔力【续】

    如何从链路层直接发送数据帧 上一篇里面提到的是从链路层"收发"数据,该篇是从链路层发送数据帧. 上一节我们主要研究了如何从链路层直接接收数据帧,可以通过bind函数来将原始套接字绑 ...

  6. UNIX网络编程——非阻塞connect:时间获取客户程序

    #include "unp.h" int connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) ...

  7. 【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数

    本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术 I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程.I/O ...

  8. 【unix网络编程第三版】阅读笔记(三):基本套接字编程

    unp第三章主要介绍了基本套接字编程函数.主要有:socket(),bind(),connect(),accept(),listen()等. 本博文也直接进入正题,对这几个函数进行剖析和讲解. 1. ...

  9. 《Unix 网络编程》14:高级 I/O 函数

    高级 I/O 函数 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ...

随机推荐

  1. javascript之alter的坑

    1.注意在使用alert返回两数之和时,会出现0.1+0.2并不等于0.3的bug 解决方法: var f=0.1; var g=0.2; alert((parseFloat(f)*100+parse ...

  2. PHP获取数组最大值下标的方法

    <?php $hots = array('8213'=> 0,'8212'=> 100,'8172'=> 10008); $key = array_search(max($ho ...

  3. 解决Acunetix 12中文汉化的方法

    最近下载一款测试软件acunetix,苦于满屏英文的苦恼,看不懂,于是乎就问度娘,结果度娘就是给中文破解包: 我是12版的,网上提供的都是11版的,没法用.怎么办呢?还好我是做测试的,平时做兼容性测试 ...

  4. [CSP-S模拟测试]:matrix(DP)

    题目描述 求出满足以下条件的$n\times m$的$01$矩阵个数:(1)第$i$行第$1~l_i$列恰好有$1$个$1$.(2)第$i$行第$r_i~m$列恰好有$1$个$1$.(3)每列至多有$ ...

  5. 用shell和python实现数组的一个例子

    目标是把字符串中的值等分为几段,取每段固定位置的值 shell脚本 #!/bin/bash ele="1 2 3 4 5 6" n= array1=() for x in $ele ...

  6. 源码编译apache设置系统启动失败

    文章为转载,亲试成功. Apache无法自动启动,1.将apachectl文件拷贝到/etc/rc.d/init.d 中,然后在/etc/rc.d/rc5.d/下加入链接即可.命令如下:cp /usr ...

  7. 【洛谷P1219 八皇后】

    参考思路见白书(一本通) 题目链接 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上 ...

  8. 基于modelforms组件实现注册功能

    数据库部分 使用的是auth_user表,添加r_pwd字段后表名变为UserInfo from django.db import models from django.contrib.auth.mo ...

  9. 007-elasticsearch5.4.3【一】概述、Elasticsearch 访问方式、Elasticsearch 面向文档、常用概念

    一.概述 Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上. Elasticsearch 也是使用 Java 编写的,它的内部使用 L ...

  10. Beetle简单构建TCP服务

    使用Beetle构建TCP服务应用是件非常简单的事情,它并不需要你去关注Socket细节,如果你想用Socket编写高性能的TCP服务,那你要关注的东西非常多,异步数据处理,大量连接下的线程管理和连接 ...