linux网络编程
A: osi七层:
应用层 用
表示层 户
会话层 态
********************************
传输层 内
网络层 核
数据链路层 态
物理层
a1: 传输层协议:
tcp(传输控制协议):可靠的,面向连接的(连接,通信,断开连接)
** tcp连接(三次握手连接)
tcp四次握手连接
udp(用户数据报协议):面向无连接,不安全
端口号(默认80):找到接收数据的地址
IP:找到接收数据的机器
a2: 网络层协议:ip(网际协议)
a3: 数据链路层标准:以太网
B: 主机字节序和网络字节序:
低位存放低地址,小端对齐(主机字节序)
低位存放高地址,大端对齐(网络字节序),使用htonl,htons,ntohs,ntohl函数,h:host to:change n:network s:short l:long
C: IP地址的转换:
字符串类型:192.168.2.123
数值类型:
in_addr_t inet_addr(const char *cp);
功能:将字符串类型ip地址转换为数值型ip地址,并且转换字节序
参数:cp----字符串类型ip地址
返回值:数值型ip地址
in_addr_t inet_network(const char *cp);
功能、参数、返回值同上,不同的是未做字节序转换
char *inet_ntoa(struct in_addr in);
功能:将数值类型ip地址转为字符串型ip地址
参数:in
struct in_addr
{
in_addr_t s_addr;
};
D: 文件描述符:
open close read write //linux提供的系统调用
分配原则:当前系统最小,并空闲的
ssize_t read(int fd, void *buf, size_t count);
功能:从文件读取内容
参数:fd----文件描述符
buf----存放读取数据的缓冲区
count----缓冲区的大小
返回值:读取的字节数 0----读取结束 -1----失败
ssize_t write(int fd, const void *buf, size_t count);
功能:往文件写入数据
参数:fd----文件描述符
buf----写入数据的缓冲区
count----缓冲区的大小
返回值:写入数据的字节数 -1-----失败
E: 被动端/服务端函数:
e1: int socket(int domain, int type, int protocol);
功能:创建网络版的文件描述符(套接字)
参数:domain-----AF_INET(ipv4协议族)
type-----套接字的类型 SOCK_STREAM=面向连接(tcp协议) SOCK_DGRAM=面向无连接(udp协议)
protocol:协议 0---根据协议族和套接字类型自动填写协议
或者:IPPROTO_TCP IPPROTO_UDP
返回值:套接字 -1-----失败
e2: int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:将IP地址和端口号与套接字绑定
接收者:只能接收绑定地址为目的地址,绑定端口号为目的端口号的报文
发送者:设置源ip地址和源端口号
参数:sockfd----套接字
addr:
struct sockaddr_in {
short sin_family; //协议族:AF_INET
short sin_port; //端口号
short in_addr sin_addr; //ip地址
}
addrlen------地址结构体的长度
返回值:0---成功 -1----失败
e3: int listen(int sockfd, int backlog);
功能:将套接字的状态修改为被动态,并建议设置内核中的完成连接队列的长度
参数:sockfd----套接字
backlog----建议值
返回值:0---成功 -1----失败
e4: int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:阻塞函数,从内核的连接完成队列中取出一个连接状态
参数:sockfd----套接字
addr----出参,带回主动端的ip地址和端口号
addrlen------地址结构体的长度
返回值:用于通信的套接字 -1----失败
F: 主动端/客户端函数:
f1: int socket(int domain, int type, int protocol);
f2: int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:发起三次握手连接
参数:sockfd----套接字
addr---被动端的ip地址和端口号
addrlen----地址结构体长度
返回值:0---成功 -1----失败
注意:
当read读取tcp数据时返回值为0表示写端/发送端关闭
当接收端关闭,发送数据端将被信号SIGPIPE杀死
H: 接收数据(属性都默认是0):
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
I: 线程操作时注意:
临界资源(多个进程(共享内存)或线程访问的资源(局部变量、全局变量))和互斥(在同一时间只有并仅有一个进程或线程可以访问临界资源)
J: 多路IO:
j1: select监听的步骤:
1.将监听的文件描述符添加到文件描述符集合 中
eg:fd_set rdfds;
FD_ZERO(&rdfds);
FD_SET(0,&rdfds);
FD_SET(confd,&rdfds);
2.调用select监听活跃的文件描述符
3.判断监听的文件描述符是否活跃
eg:FD_ISSET(0,&rdfds);
int select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
功能:监听多个I/O端口(文件描述符),采用轮询的方式监听文件描述符,所以随着监听的文件描述符的增多而使效率降低
参数:nfds---监听文件描述符中的最大值+1
readfds、writefds、exceptfds(执行的文件描述符)---监听的文件描述符的集合。这三个文集描述符既是入参(监听的文件描述符集合),也是出参(带回活跃的文件描述符集合)
timeout----监听超时的时间
返回值:监听文件描述符集合中活跃的文件描述符的个数 -1-----失败
操作文件描述符集合:
将文件描述符fd从文件描述符集合set中删除:
void FD_CLR(int fd, fd_set *set);
判断文件描述符fd在文件描述符集合set中:
int FD_ISSET(int fd, fd_set *set);
1----存在 0------不存在
将文件描述符fd添加到文件描述符集合set中:
void FD_SET(int fd, fd_set *set);
将文件描述符集合set清空:
void FD_ZERO(fd_set *set);
j2: poll()工作模式和select相同---轮询监听:
int poll(struct pollfd fds[],
nfds_t nfds,
int timeout);
参数:fds---监听的文件描述符的数组
struct pollfd {
int fd; /*监听的文件描述符*/
short events; /*感兴趣的事件*/
short revents; /*活跃的事件*/
};
nfds---数组的个数
timeout---超时时间,不超时就是 -1
返回值:监听文件描述符集合中活跃的文件描述符的个数 -1---- -失败
j3: epoll():
工作模式:只关心活跃的文件描述符,所以它不会随着监听文件描述符的增多而效率下降
int epoll_create(int size);
功能:创建epoll文件描述符
参数:size----epoll通知内核epoll最多监听的文件描述符的个数
返回值:返回文件描述符 -1-----失败
int epoll_ctl(int epfd,
int op,
int fd,
struct epoll_event *event);
功能:epoll操作监听的文件描述符
参数:epfd----epoll文件描述符
op----操作:EPOLL_CTL_ADD(将文件描述符添加到epoll中)
EPOLL_CTL_MOD(修改在epoll监听的文件描述符的事件)
EPOLL_CTL_DEL(将文件描述符从epoll中删除)
fd----要操作的文件描述符
event:
struct epoll_event {
__uint32_t events; /*感兴趣的事件*/
epoll_data_t data; /*私有数据*/
};
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
返回值:0----成功 -1-----失败
int epoll_wait(int epfd,
struct epoll_event *events,
int maxevents,
int timeout);
功能:监听文件描述符,并带回活跃的文件描述符
参数:epfd----epoll文件描述符
events------出参,带回多个活跃的文件描述符的数组
maxevents---最多可以带回多少个活跃的文件描述符
timeout-----超时时间
返回值:活跃的文件描述符的个数 -1---失败 0----超时
K: 处理“addr already in use”问题:
setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(int));
L: UDP的函数:
l1: int socket(AF_INET, SOCK_DGRAM, int 0);
l2: ssize_t sendto(int sockfd,
const void *buf,
size_t len,
int flags,
const struct sockaddr *dest_addr,
socklen_t addrlen);
功能:发送udp数据
参数:sockfd----套接字
buf------发送数据
len-----数据的长度
flags-----0--->默认属性
dest_addr:目的端的ip地址和端口号
addrlen:地址结构体长度
返回值:发送的字节数 -1---失败
l3: ssize_t recvfrom(int sockfd,
void *buf,
size_t len,
int flags,
struct sockaddr *src_addr,
socklen_t *addrlen);
功能:接收数据
参数:sockfd----套接字
buf----接收数据的缓冲区
len----缓冲区的长度
flags----0-->默认属性
src_addr----出参,带回发送端的ip地址和端口号
addrlen:地址结构体的长度
返回值:收到的信息 -1---失败
注意:
在udp中只要调用recvfrom,就必须设置源端口号(bind)
M: udp广播:
打开广播功能:
setsockopt(sockfd,
SOL_SOCKET,
SO_BROADCAST,
&on,
sizeof(int)); 192.168.2.255
N: 组播(多播):
组播ip地址:224.0.0.0~239.255.255.255
特殊的组播地址:
224.0.0.1:所有具有组播功能的节点(主机 路由器)
224.0.0.2:所有具有组播功能的路由器
支持组播功能的命令:
route add -net 224.0.0.0 netmask 240.0.0.0 dev em1(em1---连接网卡的名称)
将本机IP地址添加到组播地址中:
setsockopt(sockfd,
IPPROTO_IP,
IP_ADD_MEMBERSHIP,
&mreq,
sizeof(struct ip_mreq));
struct ip_mreq
{
struct in_addr imr_multiaddr; //组播地址
struct in_addr imr_interface; //本机地址
};
O: 关闭防火墙:
# service iptables stop //临时关闭防火墙
#chkconfig iptables off
#vim /etc/selinux/config 修改SELINUX = disabled
P: 登录:
char *getpass(const chat *prompt);
功能:接收密码
参数:prompt-----提示信息
返回值:接收的密码
struct spwd *getspnam(const char *name);
功能:根据用户名name返回/etc/shadow文件的内容
char *crypt(const char *key, const char *salt);
功能:将key加密
参数:key----明码
salt-----参照
返回值:加密后的密码
Q: ftp功能:
1.登录(服务器端的系统用户名称和密码)
2.pwd:显示服务器端当前的操作目录
用户登录成功后的路径:登录用户的家目录
3.cd:切换命令的名称(../..)
cd命令的结果:250 Directory successfully changed.
550 Failed to change directory.
4.ls:浏览服务器端的当前目录下的内容
ls命令的结果:文件类型、文件权限、硬链接数、用户id、用户组的id、大小、时间、文件名称
5.get:从服务器端下载文件,下载的文件存放到当前登录服务器的目录下
6.put:将客户端的文件上传到服务器端上,存放上传文件的目录是当前服务器的目录
7.quit:客户端结束运行
客户端功能:
接收命令和参数,将命令和参数发送给服务器,并等待命令的结果
命令:enum ftp_cmd
{
CMD_LOGIN,
CMD_PWD,
CMD_CD,
CMD_LS,
CMD_PUT,
CMD_GET,
CMD_QUIT,
CMD_MAX
};
struct arg_login
{
char login_user[512];
char login_pwd[512];
};
struct cli_to_ser
{
int ftp_cmd; //命令
union
{
struct arg_login argLogin;
char argCd[1024];
char argGet[1024];
char argPut[1024];
}ftp_arg;
};
等待结果:struct ser_to_cli
{
int result; //0---登录成功 -1----失败 -2---Failed to change directory. 1----Directory successfully changed. 2---ls命令完毕 3--get/put失败
char string_result[512];
};
服务器功能:1.接收进程-----负责接收数据
| struct recv_to_opt
| {
(无名管道) | struct cli_to_ser data;
| struct sockaddr_in cli_addr;
| };
2.处理进程-----负责查看客户端是否以前登录过服务器,如果没有登录服务器,则记录客户端的登录信息,并创建子进程为客户端服务。如果登录过服务器,直接将数据封装完毕后发送给客户端对应的子进程。
|
| (每个子进程---处理进程:创建一个众所周知的管道)
| 或者
| (消息队列)
|
3.子进程集----负责处理命令,并将处理结果发送给对应的客户端
注意:
1.文件传输时使用tcp,客户端是被动端,服务器端子进程是主动端
2.当服务器端子进程接收到quit命令时,子进程将登录表中的客户端对应的信息删除,子进程向客户端发送quit命令执行成功,子进程消亡,该子进程的父进程一定为其收尸,避免僵尸进程。
客户端登录表(临界资源,在共享内存---互斥(信号量)中开辟空间,以数组的方式存储):
struct cli_login_table
{
struct in_addr cli_addr;
pid_t child_pid;
};
R: ipv6:
1.查看是否有ipv6模块
lsmod | grep ipv6
2.开启ipv6功能:
vim /etc/sysconfig/network--------》NETWORKING_IPV6=yes
3.ipv6的地址:
ipv4的地址长度是32b(4个bytes)
ipv6的地址长度是128b(16个bytes)
fe80::d6be:d9ff:fed4:90be/64-----64区分网络段和主机段,所以ipv6没有子网掩码
4.特殊的ipv6地址:
0:0:0:0:0:0:0:0------>INADDR_ANY
::1--------->127.0.0.1
5.临时设置ipv6地址
ifconfig em1 add ipv6地址
长久设置:
vim /etc/sysconfig/network-scripts/ifcfg-em1---------》IPV6INIT=yes IPV6ADDR=IPV6地址
6.ipv6地址结构体
struct sockaddr_in6
{
sin6_family;
sin6_port;
sin6_addr;
};
S: unix域套接字(不是协议):
应用于:进程间通信
协议族:AF_LOCAL
地址结构体:struct sockaddr_un
{
short sun_family; //AF_LOCAL--tcp AF_UNIX---udp
char sun_path[]; //地址就是一个文件
};
计算地址结构体的长度:SUN_LEN(&address);
T: 设置tags文件:
1.进入要设置tags的目录
2.生成tags文件:ctags -R
3.把tags文件添加到vim中:vim /etc/vimrc 加入 set tags=/usr/include/tags
linux网络编程的更多相关文章
- 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"
[深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...
- 【linux草鞋应用编程系列】_5_ Linux网络编程
一.网络通信简介 第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章. 二.linux网络通信 在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...
- Linux 网络编程(IO模型)
针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...
- linux网络编程 no route to host 解决方案
linux网络编程 no route to host 解决方案 [整合资料] (2013-05-13 21:38:12) 转载▼ 标签: net iptables it 分类: Linux 参考资料h ...
- linux网络编程-(socket套接字编程UDP传输)
今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...
- Linux网络编程&内核学习
c语言: 基础篇 1.<写给大家看的C语言书(第2版)> 原书名: Absolute Beginner's Guide to C (2nd Edition) 原出版社: Sams 作者: ...
- linux网络编程_1
本文属于转载,稍有改动,以利于学习. (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个 ...
- Linux网络编程入门 (转载)
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
- Linux网络编程必看书籍推荐
首先要说讲述计算机网络和TCP/IP的书很多. 先要学习网络知识才谈得上编程 讲述计算机网络的最经典的当属Andrew S.Tanenbaum的<计算机网络>第五版,这本书难易适中. &l ...
- [转] - Linux网络编程 -- 网络知识介绍
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
随机推荐
- R自动数据收集第二章HTML笔记1(主要关于handler处理器函数和帮助文档所有示例)
本文知识点: 1潜在畸形页面使用htmlTreeParse函数 2startElement的用法 3闭包 4handler函数的命令和函数体主要写法 5节点的丢弃,取出,取出标签名称.属性.属 ...
- Xms Xmx PermSize MaxPermSize 区别
Eclipse崩溃,错误提示: MyEclipse has detected that less than 5% of the 64MB of Perm Gen (Non-heap memory) s ...
- Dom4J解析技术
前面的话 本文主要讲解有关Dom4j技术和xpath配合下的优化! 目录: 为什么需要Dom4J DOM4J怎么用 xpath怎么配合DOM4J 一 为什么需要Dom4J 一 ...
- Fiddler将笔记本设置代理,抓取手机网络请求包
第一步:下载fiddler,下载地址:http://www.telerik.com/download/fiddler 第二步:安装fiddler,略过... 第三步:启动fiddler,启动后界面如下 ...
- laravel数据库迁移(三)
laravel号称世界上最好的框架,数据库迁移算上一个,在这里先简单入个门: laravel很强大,它把表中的操作写成了migrations迁移文件,然后可以直接通过迁移文件来操作表.所以 , 数据迁 ...
- break与continue的区别
break 在while.for.do...while.while循环中使用break语句退出当前循环,直接执行后面的代码. continue 的作用是仅仅跳过本次循环,而整个循环体继 ...
- gulp图片压缩
gulp图片压缩 网页性能优化,通常要处理图片,尤其图片量大的时候,更需要工具来批量处理,这里使用gulp,做个简单总结 image-resize压缩尺寸 var gulp = require('gu ...
- Git 如何只更新项目中某个目录里的文件
Git由于在远端和本地都有一个代码库, 这样更新单个文件比SVN要麻烦一点. 1. 如果想拿远端git服务器上的最新版本(或某个特定版本)覆盖本地的修改,可以使用git pull命令, 但这会 ...
- jQuery插件中的this指的是什么
在jQuery插件的范围里, this关键字代表了这个插件将要执行的jQuery对象, 但是在其他包含callback的jQuery函数中,this关键字代表了原生的DOM元素.这常常会导致开发者误将 ...
- 在Centos中部署redis运行状态图形化监控工具 — RedisLive
写在前面 前两天看到张善友老师的一篇文章<先定个小目标, 使用C# 开发的千万级应用>,里面给出了一张腾讯OA基础服务中redis运行情况的一张监控图,然后想到自己的项目中前不久也上了re ...