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网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
随机推荐
- windows server 2012 使用问题
1.端口映射,把宿主机的端口映射到hyper-v创建的虚拟机上 访问宿主机的公网IP的某个端口,就等于访问这个虚拟机上的端口 具体实现: 在宿主机上命令行输入 添加一个端口映射 netsh inter ...
- PHP获取接口数据(模拟Get)
当我们在做PHP开发的时候,很多时候需要对接口进行测试,或者更方便的调用一些已有模块的接口,取到结果并进行后续操作,我们可以通过curl进行模拟提交post和get请求,来去实现这些功能. 之后就可以 ...
- Could not find or load main class org.gradle.wrapper.GradleWrapperMain解决办法
解决办法: gradlew is the gradle wrapper executable - batch script on windows and shell script elsewhere. ...
- ASP.Net 打通服务器代码和前台界面的特殊符号
1.<% %>用来绑定后台代码 如: < % ;i<;i++) { Reaponse.Write(i.ToString()); } %> 2.<%# %> 是 ...
- Android ExpandableGridView的实现
近期在做项目的时候碰到了这样一个布局 在android中有种实现折叠list方式是ExpandableListView 但是官方没有ExpandableGridView 那么怎么样用Expandab ...
- Android源代码查看途径
作为一个android coder,多阅读android源码对提高android开发水平是很有帮助的,那么我们可以通过哪些途径查看android源码呢 1.如果你能够FQ的话可以去android官网查 ...
- 3D游戏编程大师技巧──环境搭建
刚开微博,想借助这个平台与大家交流,写下自己的学习记录,希望得到大家的批评指正. 好了,进入主题.这段时间对游戏编程很感兴趣,于是在网友的推荐下开始学习<3D游戏编程大师技巧>这本书.今天 ...
- js中typeof和instanceof
对于typeof和instanceof,我们经常用来检测数据的类型.typeof可以检测Number.Boolean.String.Undefined类型,对于其他类型的数据都返回为object:而i ...
- navigationController 的返回按钮自定义
1: navigationController 的返回按钮自定义 SecondViewController *secondVC = [SecondViewController new]; ...
- bzoj4349: 最小树形图
最小树形图模板题…… 这种\(O(nm)\)的东西真的能考到么…… #include <bits/stdc++.h> #define N 60 #define INF 1000000000 ...