当前位置: 首页 > article >正文

网络编程复习

1.学习网络编程的目的?

使用套接字通信,来实现跨主机多进程之间的通讯

2.OSI体系结构和TCP/IP体系结构

OSI体系结构:

应用层:提供网络应用程序和用户之间的接口,实现应用程序和用户的通讯

       DNS,Telnet,FTP,TFTP,HTTP,ModbusTCP工业总线协议等

表示层:负责数据的格式化和转换,使得数据能够在不同系统能够表示和解释。负责数据的加密解密,编码解码

会话层:负责建立连接,管理,终止会话,实现通讯

传输层:负责端到端的数据传输,确保数据的可靠传输和错误恢复(TCP UDP)

网络层:负责数据的路由和转发,实现不同网络的数据传输。ip寻址

数据链路层:将数据包转化为帧,并进行帧的处理。MAC寻址

物理层:负责传输比特流,定义物理介质和电气特性,以及硬件信息。

TCP/IP

应用层,传输层,网络层,网络接口和物理层

3.三次握手

        1.客户端发送SYN报文(seq=j)给服务器

        2.服务器接收到SYN报文后,回复客户端ACK(ack=j+1)并发送SYN包(seq=k)询问下一次什么时候发送

        3.客户端接收到后回复ACK(ack=k+1)给服务器

4.四次挥手

        1.客户端向服务器发送FIN报文,客户端进入FIN_WAIT1状态

        2.服务器接收到后发送ACK报文进入CLOSE_WAIT状态,客户端进入FIN_WAIT2状态

        3.服务器完成ACK报文发送后,发送FIN报文给客户端,服务器进入LAST_ACK状态

        4.客户端接收到FIN报文后进入TIME_WAIT状态,等待一段时间(2MSL),然后关闭,服务器接收到后也关闭

5.字节序函数的使用

#define IP "192.168.1.1"
int main(int argc, const char *argv[])
{
    in_addr_t kkk = inet_addr(IP);//将IP地址转为网络IP
    printf("%x\n",kkk);

    struct in_addr mmm;
    mmm.s_addr = kkk;//将网络IP放入结构体成员中
    char *p = inet_ntoa(mmm);//将网络IP转为点分十进制IP
    printf("%s\n",p);
    return 0;
}

6.何时不需要进行主机字节序和网络字节序的转换

1、单字节整数不需要转换

2、字符串也不需要转换

(只有多字节整数才需要转换)

7.LAN和WAN

LAN:局域网,覆盖小,速度快,延时低

WAN:广域网,覆盖大,速度慢,延时高

8.IPV4地址的划分和分类

IP地址=网络号+主机号

分类:

A类: 1.0.0.0-----127.255.255.255       网络号1字节

B类:128.0.0.0---191.255.255.255        网络号2字节

C类:192.0.0.0---223.255.255.255        网络号3字节

D类(组播):224.0.0.0--239.255.255.255        网络号4字节

E类(实验室或者政府特别机构):240.0.0.0--255.255.255.255        网络号4字节

地址范围的起始,看第一个字节(8位)的前四位

A:0000   0.0.0.0 和127.0.0.0规定好不用的   127.0.0.0是回环地址,做循环测试用的.

B:10

C:110

D:1110

E:1111

9.引入子网掩码的IP

IP=网络号+子网号+主机号

子网网段由  ip地址&子网掩码组成

默认子网掩码:子网掩码就是某类网络的 网络号全是1,主机号全是0的值。

子网网段的个数 = 2^(子网掩码中1的个数)

子网网段下的主机个数 = 2^(子网中0的个数)

10.TCP服务器客户端

//服务器
#define IP "192.168.1.2"
#define PORT 8888
#define BACKLOG 30
int main()
{
    int oldfd=socket(AF_INET,SOCK_STREAM,0);
    if(oldfd==-1)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in server={
        .sin_family=AF_INET,
        .sin_port=htons(PORT),
        .sin_addr.s_addr=inet_addr(IP),
    };
    if(bind(oldfd,(struct sockaddr*)&server,sizeof(server))==-1)
    {
        perror("bind");
        return -1;
    }
    if(listen(oldfd,BACKLOG)==-1)
    {
        perror("listen");
        return -1;
    }
    struct sockaddr_in client;
    socklen_t client_len=sizeof(client);
    int newfd=accept(oldfd,(struct sockaddr*)&client,&client_len);
    if(newfd==-1)
    {
        perror("accept");
        return -1;
    }
    printf("%s发来连接请求\n",inet_ntoa(client.sin_addr));
    char buff[1024];
    while(1)
    {
        memset(buff,0,sizeof(buff));
        int len=recv(newfd,buff,sizeof(buff),0);
        if(len==0)
        {
            //客户端下线
        }
        strcat(buff,"111");
        send(newfd,buff,sizeof(buff),0);
    }
    close(oldfd);
    close(newfd);
    return 0;
}

//客户端
#define IP "192.168.1.2"
#define PORT 8888
int main()
{
    int oldfd=socket(AF_INET,SOCK_STREAM,0);
    if(oldfd==-1)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in server={
        .sin_family=AF_INET,
        .sin_port=htons(PORT),
        .sin_addr.s_addr=inet_addr(IP),
    };
    socklen_t server_len=sizeof(server);
    if(connect(oldfd,(struct sockaddr*)&server,&server_len)==-1)
    {
        perror("bind");
        return -1;
    }
    char buff[1024];
    while(1)
    {
        fgets(buff, sizeof(buff), stdin);
        buff[strlen(buff)-1]='\0';
        send(oldfd,buff,sizeof(buff),0);
        int len=recv(newfd,buff,sizeof(buff),0);
        if(len==0)
        {
            //服务器退出
            break;
        }
    }
    close(oldfd);
    return 0;
}

11.UDP服务器客户端

//服务器
#define IP "192.168.1.2"
#define PORT 8888
int main()
{
    int oldfd=socket(AF_INET,SOCK_DGRAM,0);
    if(oldfd==-1)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in server={
        .sin_family=AF_INET,
        .sin_port=htons(PORT),
        .sin_addr.s_addr=inet_addr(IP),
    };
    if(bind(oldfd,(struct sockaddr*)&server,sizeof(server))==-1)
    {
        perror("bind");
        return -1;
    }
    struct sockaddr_in client;
    socklen_t client_len=sizeof(client);
    char buff[1024];
    while(1)
    {
        memset(buff,0,sizeof(buff));
        int len=recvfrom(oldfd,buff,sizeof(buff),(struct sockaddr*)&client,&client_len);
        if (len < 0) {
            perror("recvfrom");
            break;
        }
        strcat(buff,"111");
        sendto(oldfd,buff,sizeof(buff),0,(struct sockaddr*)&client,client_len);
    }
    close(oldfd);
    return 0;
}

//客户端
#define IP "192.168.1.2"
#define PORT 8888
int main()
{
    int oldfd=socket(AF_INET,SOCK_DGRAM,0);
    if(oldfd==-1)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in server={
        .sin_family=AF_INET,
        .sin_port=htons(PORT),
        .sin_addr.s_addr=inet_addr(IP),
    };
    socklen_t server_len=sizeof(server);
    char buff[1024];
    while(1)
    {
        fgets(buff, sizeof(buff), stdin);
        buff[strlen(buff)-1]='\0';
        sendto(oldfd,buff,sizeof(buff),0,(struct sockaddr*)&client,client_len);
        memset(buff, 0, sizeof(buff));
        int len=recvfrom(newfd,buff,sizeof(buff),0,(struct sockaddr*)&client,&client_len);
        if (len < 0) {
            perror("recvfrom");
            break;
        }
    }
    close(oldfd);
    return 0;
}

12.单播广播组播

单播:一对一通信

广播:一对多通信

//设置套接字允许广播
int n=1;
if(setsockopt(oldfd,SOL_SOCKET,SO_BROADCAST,&n,sizeof(n))==-1)
{
    perror("setsockopt");
    return -1;
}

组播:一对多通信,加入多播组之间的通信

D类ip    224.0.0.0 -- 239.255.255.255

#define ZIP "224.1.2.3"
#define IP "192.168.60.66"
#define PORT 7777
struct ip_mreqn recv={
    .imr_multiaddr.s_addr=inet_addr(ZIP),//组播组IP
    .imr_address.s_addr=inet_addr(IP),//本机IP
    .imr_ifindex=2,//ens33网卡索引号
};

if(setsockopt(oldfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&recv,sizeof(recv))==-1)
{
    perror("setsockopt");
    return -1;
}

13.IO多路复用

select

fd_set readfds,temp;//定义两个集合存放描述符
int maxfd = oldfd;//保留最大的描述符
FD_ZERO(&readfds);
FD_SET(0,&readfds);
FD_SET(oldfd,&readfds);
while(1)
{
    temp=readfds;
    int res=select(2,&temp,NULL,NULL,NULL);
    if(res==0)
    {
        //超时
        continue;
    }
    if(res==-1)
    {
        perror("select");
    }
    for(int i=0;i<=maxfd;i++)
    {
        if(!FDISSET(i,&temp))//没有发生操作就下一个
        {
            continue;
        }
        if(i==oldfd)
        {
            int newfd=accept(i,(struct sockaddr *)&client,&client_len);
            FD_SET(newfd,&readfds);
            maxfd=newfd>maxfd?newfd:maxfd;
        }
        else
        {
            char buff[1024];
            memset(buff,0,sizeof(buff));
            int len = recv(i,buff,sizeof(buff),0);//0:阻塞发送 MSG_DONTWAIT:非阻塞
            if(len==0)
            {
                close(i);
                FD_CLR(i,&readfds);
                if(maxfd==i)
                {
                    maxfd--;
                }    
                break;
            }
            printf("%s\n",buff);
            fgets(buff,sizeof(buff),stdin);
            send(i,buff,sizeof(buff),0);
        }
    }

}

poll

struct pollfd fds[2];
fds[0].fd=0;
fds[0].events=POLLIN;
fds[1].fd=oldfd;
fds[1].events=POLLIN;
while(1)
{
    int res=poll(fds,2,-1);
    if(res==0)
    {
        //超时
    }
    if(res==-1)
    {
        perror("poll");
        return -1;
    }
    if(fds[1].revents==POLLIN)
    {
        //oldfd产生了事件
    }
    if(fds[0].revents==POLLIN)
    {
        //标准输入流产生了事件
    }
}

epoll

监听的最大的文件描述符没有个数限制

14.SQL数据库

1.创建表
create table if not exist stu (id int,name char);

2.插入
insert into stu (id,name) values(1,'ww')

alter table stu add column score int;//增加列

3.删除
drop table stu;//删除表

 delete from stu where id=1;
 delete from stu;    删除表格中的所有数据;

4.更改
update stu set id=5 where name="张三";

5.查找
select * from stu;
select id,name from stu;

int callback(void *arg,int n,char **msgtext ,char **msgtable)
{
    int i,j;
    for(i = 0;i<n;i++)
    {
        printf("%s\t",*(msgtable+i));//打印表头
    }
    printf("\n");

    for(j = 0;j<n;j++)
    {
       printf("%s\t",*(msgtable+j));//打印一行数据
    }
    printf("\n");
    return 0;
}


    snprintf(sql,sizeof(sql),"select * from stu1 where name=\"%s\";",name);
    if(sqlite3_exec(ppDb,sql,callback,NULL,&errmsg)==1)
    {
        perror("sqlite3_exec");
        printf("错误信息:%s\n",sqlite3_errmsg(ppDb));
        printf("错误码:%d\t出错行是:%d\n",sqlite3_errcode(ppDb),__LINE__);
    }
    char **m;
    char *errqqq = NULL;
    int hang,lie;
    snprintf(sql,sizeof(sql),"%s","select * from stu1;");
    res = sqlite3_get_table(ppDb,sql,&m,&hang,&lie,&errqqq);
    if(res!=0)
    {
        perror("sqlite3_get_table");
        printf("错误信息:%s\n",errqqq);
    }
    //get_table函数执行到此,参数全部被赋值
    //循环输出信息
    int i,j;
    printf("\n\n\n");
    for(i = 0;i<=hang;i++)
    {
        for(j = 0;j<lie;j++)
        {
            printf("%s\t",*(m+i*lie+j));
        }
        printf("\n");
    }

    sqlite3_free_table(m);//释放指向数据库表格的指针
    sqlite3_close(ppDb);//关闭数据库句柄
6.拷贝
从a中拷贝所有数据到b中:
    create table b as select * from a;
从a中拷贝指定字段到b中:
    create table b as select 字段,字段,字段 from a;


http://www.kler.cn/a/527411.html

相关文章:

  • Oracle Primavera P6 最新版 v24.12 更新 2/2
  • 论文阅读(八):结构方程模型用于研究数量遗传学中的因果表型网络
  • JVM_程序计数器的作用、特点、线程私有、本地方法的概述
  • springboot使用rabbitmq
  • 7.抽象工厂(Abstract Factory)
  • 1.Template Method 模式
  • 从0开始,来看看怎么去linux排查Java程序故障
  • Day31-【AI思考】-深度学习方法论全解析——科学提升学习效率的终极指南
  • Synology 群辉NAS安装(7)lsof指令和synogear
  • 半导体SAP管理系统:数字化转型的驱动力
  • ComfyUI使用教程、开发指导、资源下载
  • 微服务配置中心 Apollo解析——Portal 关联 Namespace
  • 什么是麦克斯韦方程
  • 2025年01月31日Github流行趋势
  • 3 Spark SQL
  • 【leetcode】T541 (两点反思)
  • 新一代搜索引擎,是 ES 的15倍?
  • ARM嵌入式学习--第十一天(中断处理 , ADC)
  • 编程大模型之—Qwen2.5-Coder
  • JVM方法区
  • Array,String,Number
  • ZZNUOJ(C/C++)基础练习1021——1030(详解版)
  • 白话DeepSeek-R1论文(二)| DeepSeek-R1:AI “升级打怪”,从“自学成才”到“全面发展”!
  • 数据结构-Stack和栈
  • python学opencv|读取图像(五十二)使用cv.matchTemplate()函数实现最佳图像匹配
  • FBX SDK的使用:基础知识