Linux——网络编程总结性学习
创始人
2024-02-10 08:34:41

什么是ISP?

网络业务提供商_百度百科

计算机网络有哪些分类方式,计算机网络有哪些分类?_陈泽杜的博客-CSDN博客

路由器_百度百科

 目前实际的网络分层是TCP/IP四层协议

当我们浏览⽹站找到想要下载的⽂件以后,找到相应的接⼝点击下载就好了。剩下的⼯作就交给⽹ 络了,那么⽹络是如果传输的呢?

        答案就是先封包然后再拆包。实际的远距离传输,可能会涉及多个⽹络,多个路由器。这⾥简化成 ⼀个来表示。我们看到,每⼀层都有相应的控制信息,需要加到数据前⾯,我们把这些控制信息称之为 包头。每层都有不同我包头,⽐如应⽤层可能就是FTP的包头,然后,传输层可能就是TCP包头,再往下 传输层: 应⽤层: 数据的封包与拆包 7 依次就是IP包,以太⽹ (Ethernet),到了物理层以后,上层交下来的数据,就会变成bit流,被放的实 际的物理设备上进⾏传输。

        如果⽬标在本⽹络内部,数据就会被直接发送的⽬标主机上⾯,作相反的操作,也就是拆包。⼀般 我们下载的⽂件基本上都存在于远程的服务器。所以,必然要经过多个⽹络,多个路由器。每个路由器 都按照如图所示的步骤,层层拆包,折到⽹络层的IP头以后,和⾃⼰的⼀个叫做路由表的东⻄进⾏⽐ 对,确定⼀个合适的⽹络地址,按照新的⽹络地址再次进⾏封装。下⼀个路由器⽣复这个动作,直到把 数据传送给⽬标主机为⽌。

        最后,再由⽬标主机,也就是你的电脑,进⾏拆包。然后把数据展示给你或者直接存储到磁盘上。

网络程序的架构

⽹络程序通常有两种架构,⼀种是

B/S(Browser/Server,浏览器/服务器)架构

⽐如我们使⽤⽕狐浏览器浏览Web⽹站,⽕狐浏览器就是⼀个Browser,⽹站上运⾏的Web就是⼀个服 务器。这种架构的优点是⽤户只需要在⾃⼰电脑上安装⼀个⽹⻚浏览器就可以了,主要⼯作逻辑都在服 务器上完成,减轻了⽤户端的升级和维护的⼯作量。

另外⼀种架构是C/S(Client/Server,客户机/服务器)架构

这种架构要在服务器端和客户端分部安装不同的软件,并且不同的应⽤,客户端也要安装不同的客户机 软件,有时候客户端的软件安装或升级⽐较复杂,维护起来成本较⼤。但此种架构的优点是可以较充分 地利⽤两端的硬件能⼒,较为合理地分配任务。值得注意的是,客户机和服务器实际指两个不同的进 程,服务器是提供服务的进程,客户机是请求服务和接受服务的进程,它们通常位于不同的主机上(也 可以是同⼀主机上的两个进程),这些主机有⽹络连接,服务器端提供服务并对来⾃客户端进程的请求 做出响应。⽐如我们常⽤的QQ,我们⾃⼰电脑上的QQ程序就是⼀个客户端,⽽在腾讯公司内部还有服 务器端器程序。

基于套接字的⽹络编程中,通常使⽤C/S架构。⼀个简单的客户机和服务器之间的通信过程如下: 1. 客户机向服务器提出⼀个请求

2. 服务器收到客户机的请求,进⾏分析处理

3. 服务器将处理的结果返回给客户机 通常,⼀个服务器可以向多个客户机提供服务。因此对服务器来说,还需要考虑如何有效地处理多个客 户机的请求。 

 这里的ip是公网ip,局域网也一样,在一个局域网内IP也不能相同,他们经过一个路由统一封装成公网ip。

 网络桥接_百度百科

从前192.168是专用局域网段

 

 一般不使用的特殊ip

 

IP地址是分等级的地址结构,分两个等级的好处是

 (3) 地址掩码 ⼜称为⼦⽹掩码 (subnet mask)。

位数:32 位。

⽬的:让机器从 IP 地址迅速算出⽹络地址。

由⼀连串 1 和接着的⼀连串 0 组成,⽽ 1 的个数就是⽹络前缀的⻓度。

/20 地址块的地址掩码:11111111 11111111 11110000 00000000

点分⼗进制记法:255.255.240.0

CIDR 记法:255.255.240.0/20。

默认地址掩码

 

 IP地址在Linux当中的实现

 IP地址是⼀个32位的数据

通常被封装成如下数据类型

struct in_addr { uint32_t s_addr; };

in_addr_t

uint32_t

 

 

 常用的熟知端口

 

计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。但是,人类还是习惯读写大端字节序。所以,除了计算机的内部处理,其他的场合比如网络传输和文件储存,几乎都是用的大端字节序。正是因为这些原因才有了字节序。

计算机处理字节序的时候,如果是大端字节序,先读到的就是高位字节,后读到的就是低位字节。小端字节序则正好相反

#include 
typedef unsigned char byte;
typedef unsigned int word;//#define N 1int main(int argc, char *argv[])
{word val32 = 0x11223344;byte val8 = *( (byte*)&val32 );	if(val8 == 0x44)printf("本机是⼩端字节序\n");elseprintf("本机是⼤端字节序\n");int c = 1;//int *a = c;char b = *(char*)&c;printf("%p %d\n",&c ,b);return 0;
}

 

#include 
#include 
typedef unsigned char byte;
typedef unsigned int word;
int main(int argc, char *argv[])
{word val32 = 0x11223344;byte val8 = *( (byte*)&val32 );if(val8 == 0x44){printf("本机是⼩端字节序\n");val32 = htonl(val32);val8 = *( (byte*)&val32 );if(val8 == 0x44)printf("字节序没有转换\n");elseprintf("转换成功, 现在是⽹络字节序了\n");}return 0;
}

 IP地址的转换函数

 

来个小实验,使用本机的两个虚拟机根据ip和端口号通信

 

只能一对一谁手快和谁通信

 服务器是如何实现每台服务器都是公网IP的呢?

socket分类

 

 

 

流式套接字对应TCP数据报套接字对应UDP,所以protocol是0,只用用原始套接字时才需要有参数。

 套接字不知用于网络通信也可用于进程间通信,在网络通信中可选用IIPV4和IPV6

 

 

!g就是shell中上次输入的g开头的命令

#include 
#include 
#include 
#include 
#include int main(int argc, char **argv)
{int fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8888);addr.sin_addr.s_addr = inet_addr("192.168.26.128");if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)))//成功0/失败-1{perror("bind");exit(0);}struct sockaddr_in sin;socklen_t sinlen = sizeof(addr);if(getsockname(fd, (struct sockaddr *)&sin, &sinlen)){perror("getsockname");exit(0);}printf("文件描述符%d绑定地址是%s,端口号%d\n", fd, inet_ntoa(sin.sin_addr),ntohs(sin.sin_port));return 0;
}

 

 

 

 

 

 

 

#include 
#include 
#include 
#include 
#include 
#include 
#define BACKLOG 5//可以有5个等待在队列中int main(int argc, char **argv)
{int fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8888);addr.sin_addr.s_addr = inet_addr("192.168.26.128");if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)))//成功0/失败-1{perror("bind");exit(0);}struct sockaddr_in sin;socklen_t sinlen = sizeof(addr);if(getsockname(fd, (struct sockaddr *)&sin, &sinlen)){perror("getsockname");exit(0);}printf("文件描述符%d绑定地址是%s,端口号%d\n", fd, inet_ntoa(sin.sin_addr),ntohs(sin.sin_port));if(listen(fd, BACKLOG)){perror("listen");exit(0);}printf("listen...\n");struct sockaddr_in cin;socklen_t cinlen = sizeof(cin);int newfd = accept(fd, (struct sockaddr *)&cin, &cinlen);//int newfd = accept(fd, NULL, NULL);if(newfd < 0){perror("accept");exit(0);}printf("文件描述符%d绑定IP地址%s,端口号%d\n", newfd, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));char buf[1024] = {};read(newfd, buf, 1024);printf("%s\n", buf);close(newfd);close(fd);return 0;
}

 还是用nc这次可以看连接服务器用户的相关信息

 

 

 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
int main(int argc, char *argv[])
{if(argc != 3){printf("%s [IP][PORT]\n", argv[0]);exit(0);}
/*1.创建套接字*/int fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}
/*2.设置通信结构体*/struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(atoi(argv[2]));sin.sin_addr.s_addr = inet_addr(argv[1]);
/*3.向服务端发起连接请求*/if(connect(fd, (struct sockaddr *)&sin, sizeof(sin))){perror("connect");exit(0);	}socklen_t sinlen = sizeof(sin);if(getsockname(fd, (struct sockaddr *)&sin, &sinlen)){perror("getsockname");exit(0);}printf("文件描述符%d绑定IP地址%s,端口号%d\n", fd, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
/*4.通信*/char buf[1024] = {"test\n"}; //8142	write(fd, buf, strlen(buf)+1);memset(buf, 0, 1024);//printf("input->");//fgets(buf, , stdin);//write(fd, buf, strlen(buf)+1);read(fd, buf, 1024);printf("buf = %s\n", buf);close(fd);return 0;
}
#include 
#include 
#include 
#include 
#include 
#include 
#define BACKLOG 5//可以有5个等待在队列中int main(int argc, char *argv[])
{if(argc != 3){fprintf(stderr, "%s [IP] [PORT] \n", argv[0]);exit(0);}int fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(atoi(argv[2]));addr.sin_addr.s_addr = inet_addr(argv[1]);if(bind(fd, (struct sockaddr *)&addr, sizeof(addr)))//成功0/失败-1{perror("bind");exit(0);}struct sockaddr_in sin;socklen_t sinlen = sizeof(addr);if(getsockname(fd, (struct sockaddr *)&sin, &sinlen)){perror("getsockname");exit(0);}printf("文件描述符%d绑定地址是%s,端口号%d\n", fd, inet_ntoa(sin.sin_addr),ntohs(sin.sin_port));if(listen(fd, BACKLOG)){perror("listen");exit(0);}printf("listen...\n");struct sockaddr_in cin;socklen_t cinlen = sizeof(cin);int newfd = accept(fd, (struct sockaddr *)&cin, &cinlen);//int newfd = accept(fd, NULL, NULL);if(newfd < 0){perror("accept");exit(0);}printf("文件描述符%d绑定IP地址%s,端口号%d\n", newfd, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));char buf[1024] = {};read(newfd, buf, 1024);printf("%s\n", buf);close(newfd);close(fd);return 0;
}

 

 

 哈哈天天ping百度百度不爱搭理了,ping一下华清试试 

socket有两个缓冲区一个发送一个接收

 

 

#include "net.h"
int main(int argc, char *argv[])
{
if(argc != 3)
{
printf("%s [IP][PORT]\n", argv[0]);
exit(0);
}
/*1.创建套接字*/
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0)
{
perror("socket");
exit(0);
}
/*2.设置通信结构体*/
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(atoi(argv[2]));
sin.sin_addr.s_addr = inet_addr(argv[1]);
/*3.向服务端发起连接请求*/
if(connect(fd, (struct sockaddr *)&sin, sizeof(sin)))
{
perror("connect");
exit(0);
}
/*4.通信*/
char buf[BUFSIZ];
while(1)
{
bzero(buf, BUFSIZ);
printf("input->");
fgets(buf, BUFSIZ, stdin);
send(fd, buf, strlen(buf)+1, 0);
printf("buf = %s\n", buf);
if(buf[0] == '#')
break;
}
close(fd);
return 0;
}

 

 

 

相关程序参考Linux——UDP_宇努力学习的博客-CSDN博客 

先win+R wt 然后telnet 

win上没有nc可以用telnet

 

 

 看以往文章

这里记录一个老师写的大型群体交流服务器

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include #define BACKLOG 5void handle(int sig)
{printf("child process exit...\n");wait(NULL);
}int main(int argc, char *argv[])
{if(argc != 3){printf("%s[IP][PORT]\n", argv[0]);exit(0);}signal(SIGCHLD, handle);int fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){perror("socket");exit(0);}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(atoi(argv[2]));addr.sin_addr.s_addr = inet_addr(argv[1]);if( bind(fd, (struct sockaddr *)&addr, sizeof(addr)) ){perror("bind");exit(0);}struct sockaddr_in sin;socklen_t sinlen = sizeof(addr);if(getsockname(fd, (struct sockaddr *)&sin, &sinlen)){perror("getsockname");exit(0);}printf("文件描述符%d绑定的IP地址是%s,端口号%d\n", fd, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));if( listen(fd, BACKLOG) ){perror("listen");exit(0);}printf("listen...\n");pid_t pid;int newfd;char buf[1024] = {};struct sockaddr_in cin;socklen_t cinlen = sizeof(cin);while(1){newfd = accept(fd, (struct sockaddr *)&cin, &cinlen);if(newfd < 0){perror("accept");exit(0);}printf("文件描述符%d绑定的IP地址是%s,端口号%d\n", newfd, inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));pid = fork();if(pid < 0){perror("fork");exit(0);}else if(!pid){close(fd);while(1){memset(buf, 0, 1024);if(!read(newfd, buf, 1024))break;printf("%s\n", buf);}close(newfd);exit(0);}elseclose(newfd);}close(fd);return 0;
}

select实现服务器

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;
typedef struct Node{int fd;struct Node *next;
}Node;#define BACKLOG 5void Argment(int argc, char *argv[]);
void NodeCreate(Node **p);
void AcceptHandle(int sfd, Node **H);
int ClientHandle(int fd);int main(int argc, char *argv[])
{int ret, sfd, nfd = 0;Addr_in saddr;fd_set rfds;Node *H, *p = NULL;Argment(argc, argv);NodeCreate(&H);sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){perror("socket");exit(0);}saddr.sin_family = AF_INET;saddr.sin_port = htons(atoi(argv[2]));saddr.sin_addr.s_addr = inet_addr(argv[1]);if(bind(sfd, (Addr *)&saddr, sizeof(Addr_in))){perror("bind");exit(0);}if(listen(sfd, BACKLOG)){perror("listen");exit(0);}H->fd =sfd;while(1){FD_ZERO(&rfds);p = H;nfd = 0;while(p != NULL){if(p->fd > nfd)nfd = p->fd;FD_SET(p->fd, &rfds);p = p->next;}printf("nfd = %d run select...\n", nfd);ret =select(nfd+1, &rfds, NULL, NULL, NULL);if(!ret)continue;if(ret < 0){perror("select");exit(0);}p = H;while(p->next != NULL){if(FD_ISSET(p->fd, &rfds)){if(ClientHandle(p->fd) <= 0){close(p->fd);Node *q = p->next;p->fd = q->fd;p->next = q->next;free(q);continue;}}p = p->next;}if(FD_ISSET(p->fd, &rfds))AcceptHandle(p->fd, &H);
#if 1p = H;puts("");printf("Node:");while(p != NULL){printf("%d ", p->fd);p = p->next;}
#endifif(H->next == NULL)break;}close(sfd);free(H);return 0;
}void Argment(int argc, char *argv[])
{if(argc != 3){fprintf(stderr, "%s [addr] [port]\n", argv[0]);exit(0);}
}void NodeCreate(Node **p)
{*p = malloc(sizeof(Node));if(p == NULL){perror("malloc");exit(0);}bzero(*p, sizeof(Node));
}void AcceptHandle(int sfd, Node **H)
{Node *p = NULL;Addr_in caddr;socklen_t caddr_len = sizeof(Addr_in);int cfd = accept(sfd, (Addr *)&caddr, &caddr_len);if(cfd < 0){perror("accept");exit(0);}fprintf(stderr, "client %s:%d connect success.\n",inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));NodeCreate(&p);p->fd = cfd;p->next = *H;*H = p;
}int ClientHandle(int fd)
{int ret;char buf[1024] = {};ret = recv(fd, buf, 1024, 0);if(ret <= 0)return 0;printf("fd=%d buf = %s\n",fd, buf);if(buf[0] == '#')return 0;return ret;
}

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...