嵌入式学习-网络编程-Day4

发布时间:2024年01月17日

思维导图

Day4.png

广播通信模型

#include <myhead.h>
int main(int argc, char const *argv[])
{
    int rfd =socket(AF_INET,SOCK_DGRAM,0);
    if(rfd==-1)
    {
        perror("socket error");
        return -1;
    }

    //填充地址信息结构体
    struct sockaddr_in rin;
    rin.sin_family=AF_INET;
    rin.sin_port=htons(6789);
    rin.sin_addr.s_addr=inet_addr("192.168.123.255");

    //3绑定
    if(bind(rfd,(struct sockaddr*)&rin,sizeof(rin))==-1)
    {
        perror("bind error");
        return -1;
    }

    //接收消息
    char rbuf[128]="";
    while (1)
    {
        //清空数组
        bzero(rbuf,sizeof(rbuf));

        //接受消息
        recvfrom(rfd,rbuf,sizeof(rbuf),0,0,0);

        printf("收到消息为:%s\n",rbuf);
    }
    //关闭套接字
    close(rfd);
    
    return 0;
}
#include <myhead.h>
int main(int argc, char const *argv[])
{
    //创建套接字
    int sfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sfd==-1)
    {
        perror("socket error");
        return -1;
    }

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


    //绑定(随意)
    //填充接收端地址信息结构体
    struct sockaddr_in cin;
    cin.sin_family=AF_INET;
    cin.sin_port=htons(6789);
    cin.sin_addr.s_addr=inet_addr("192.168.123.255");
    //发送消息
    char sbuf[128]="";
    while(1)
    {
        printf("请输入>>>");
        fgets(sbuf,sizeof(sbuf),stdin);
        sbuf[strlen(sbuf)-1]=0;

        //发送到广播地址
        sendto(sfd,sbuf,sizeof(sbuf),0,(struct sockaddr*)&cin,sizeof(cin));
    }
    //关闭套接字
    close(sfd);
    return 0;
}

组播通信模型

#include <myhead.h>
int main(int argc, char const *argv[])
{
    //创建套接字
    int rfd =socket(AF_INET,SOCK_DGRAM,0);
    if(rfd==-1)
    {
        perror("socket error");
        return -1;
    }
    //设置网络属性
    struct ip_mreqn im;
    im.imr_multiaddr.s_addr=inet_addr("224.1.2.3");
    im.imr_address.s_addr=inet_addr("192.168.122.60");//本机IP
    im.imr_ifindex=2;        //网络索引

    if((setsockopt(rfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&im,sizeof(im)))==-1)
    {
        perror("setsockopt error");
        return -1;
    }
    printf("加入多播组成功\n");
    //填充地址信息结构体
    
    //绑定
    struct sockaddr_in rin;
    rin.sin_family=AF_INET;
    rin.sin_port=htons(9999);
    rin.sin_addr.s_addr=inet_addr("224.1.2.3");

    if((bind(rfd,(struct sockaddr*)&rin,sizeof(rin)))==-1)
    {
        perror("bind error");
        return -1;
    }
    //接收消息
    char rbuf[128]="";
    while(1)
    {
        bzero(rbuf,sizeof(rbuf));
        recvfrom(rfd,rbuf,sizeof(rbuf),0,0,0);
        printf("收到消息为:%s\n",rbuf);
    }
    //关闭套接字
    close(rfd);
    return 0;
}

#include <myhead.h>
int main(int argc, char const *argv[])
{

    int sfd =socket(AF_INET,SOCK_DGRAM,0);
    if(sfd==-1)
    {
        perror("socket error");
        return -1;
    }

    //填充地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family=AF_INET;
    sin.sin_port=htons(9999);
    sin.sin_addr.s_addr=inet_addr("224.1.2.3");

    char sbuf[128]="";
    while(1)
    {
        printf("请输入>>>");
        fgets(sbuf,sizeof(sbuf),stdin);
        sbuf[strlen(sbuf)-1]=0;

        sendto(sfd,sbuf,sizeof(sbuf),0,(struct sockaddr*)&sin,sizeof(sin));
        printf("发送成功\n");

    }
    close(sfd);
    return 0;
}

流式域套接字模型

#include <myhead.h>
int main(int argc, char const *argv[])
{
    //创建套接字
    int sfd=socket(AF_UNIX,SOCK_STREAM,0);
    if(sfd==-1)
    {
        perror("socket error");
        return -1;
    }
    
    //由于域套接字的绑定函数,只能绑定一个不存在的套接字文件中
    //所以在绑定之前需要判断当前文件是否存在

    //判断文件是否存在函数
    if(access("./unix",F_OK)==0)
    {
        //表示文件存在,删除该文件
        if(unlink("./unix")==-1)
        {
            perror("unlink error");
            return -1;
        }
    }

    //填充地址信息结构体
    struct sockaddr_un sun;
    sun.sun_family=AF_UNIX;
    strcpy(sun.sun_path,"./unix");
    //绑定地址信息结构体
    if((bind(sfd,(struct sockaddr*)&sun,sizeof(sun)))==-1)
    {
        perror("bind error");
        return -1;
    }
    puts("bind success");
    //监听
    if(listen(sfd,128)==-1)
    {
        perror("listen error");
        return -1;
    }

    //阻塞接受客户端的连接请求
    struct sockaddr_un cun;
    socklen_t socklen=sizeof(cun);

    int newfd=accept(sfd,(struct sockaddr*)&cun,&socklen);
    if(newfd==-1)
    {
        perror("accept error");
        return -1;
    }

    //收发数据
    char buf[128]="";
    while(1)
    {
        bzero(buf,sizeof(buf));
        int res=recv(newfd,buf,sizeof(buf),0);
        if(res==0)
        {
            printf("客户端已经下线\n");
        }
        printf("[%s]:%s\n",cun.sun_path,buf);
    }
    //关闭套接字
    close(newfd);
    close(sfd);

    return 0;
}
#include <myhead.h>

int main(int argc, const char *argv[])
{
	//1.创建套接字
	int cfd  = socket(AF_UNIX,SOCK_STREAM,0/*IPPROTO_TCP*/);

	if(cfd==-1)
	{
		perror("socket error");
		return -1;
	}

	printf("cfd=%d\n",cfd);

	//2.绑定(随意)
    if(access("./linux",F_OK)==0)
    {
        if(unlink("./lunix")==-1)
        {
            perror("unlink error");
            return -1;
        }        
    }
    struct sockaddr_un cun;
	cun.sun_family=AF_UNIX;
    strcpy(cun.sun_path,"./lunix");

    if((bind(cfd,(struct sockaddr*)&cun,sizeof(cun)))==-1)
    {
        perror("bind error");
        return -1;
    }    
    puts("bind success");
	//3.连接服务器
	//3.1填充地址信息结构体
	struct sockaddr_un sun;
	sun.sun_family=AF_UNIX;
    strcpy(sun.sun_path,"./unix");

	//3.2链接
	if(connect(cfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
	{
		perror("connect error");
		return -1;
	}
	printf("链接成功\n");
	
	//4.收发数据
	char buf[128]="";
	while(1)
	{
		bzero(buf,sizeof(buf));
		printf("请输入>>>");
		fgets(buf,sizeof(buf),stdin);
		buf[strlen(buf)-1]=0;
		//发送给服务器
		send(cfd,buf,sizeof(buf),0);
		printf("发送成功\n");
		if(strcmp(buf,"quit")==0)
		{
			break;
		}

	}

	//5.关闭套接字
	close(cfd);

	return 0;
}

报式域套接字模型

#include <myhead.h>
#define SER_PORT 9999
#define SER_IP "192.168.122.36"

int main(int argc, char const *argv[])
{
    //创建套接字
    int sfd=socket(AF_UNIX,SOCK_DGRAM,0);
    if(sfd==-1)
    {
        perror("");
        return -1;
    }
    printf("sfd=%d\n",sfd);

    if(access("./linux",F_OK)==0)
    {
        if(unlink("./lunix")==-1)
        {
            perror("unlink error");
            return -1;
        }        
    }
    //2绑定
    struct sockaddr_un sun;
	sun.sun_family=AF_UNIX;
    strcpy(sun.sun_path,"./linux");

	//2.2绑定
	if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
	{
		perror("bind error");
		return -1;
	}
    //3.数据收发
    char buf[128]="";
    struct sockaddr_un cun;
    socklen_t socklen=sizeof(cun);

	while(1)
	{
		bzero(buf,sizeof(buf));
        //read(sfd,buf,sizeof(buf));
        
        //读取信息,并将客户端地址信息结构体存储到cin中
        recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,&socklen);

        printf("读取的消息为:%s\n",buf);

        //将字符串连接后回发
        strcat(buf,"=-=");
       // if((write(sfd,buf,sizeof(buf)))==-1)
        if((sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,sizeof(cun)))==-1)
        {
            perror("sendto error");
            return -1;
        }
    }

    close(sfd);
    return 0;
}

#include <myhead.h>
int main(int argc, char const *argv[])
{
    //创建用于通信的套接字文件描述符
    int cfd = socket(AF_UNIX,SOCK_DGRAM,0);
    if(cfd==-1)
    {
        perror("socket error");
        return -1;
    }
    
    if(access("./unix",F_OK)==0)
    {
        if(unlink("./unix")==-1)
        {
            perror("unlink error");
            return -1;
        }        
    }

    struct sockaddr_un cun;
	cun.sun_family=AF_UNIX;
    strcpy(cun.sun_path,"./unix");

    if(bind(cfd,(struct sockaddr*)&cun,sizeof(cun))==-1)
	{
		perror("bind error");
		return -1;
	}

    struct sockaddr_un sun;
	sun.sun_family=AF_UNIX;
    strcpy(sun.sun_path,"./linux");

    char buf[128]="";
    while(1)
	{
        printf("请输入:");
		fgets(buf,sizeof(buf),stdin);
		buf[strlen(buf)-1]=0;

        sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sun,sizeof(sun));

        if(strcmp(buf,"quit")==0)
		{
			break;
		}

        recvfrom(cfd,buf,sizeof(buf),0,0,0);
        printf("收到消息为:%s\n",buf);
    }

    return 0;
}

作业:编写一个客户端,通过TFTP服务器实现文件的上传和下载

#include<myhead.h>
#define SER_PORT 69
#define SER_IP "192.168.122.71"

int do_download(int cfd,struct sockaddr_in sin)
{
    //向服务器发送下载请求

    char buf[516] = "";
	 //组装请求数据
    short *p1 = (short *)buf;
    *p1 = htons(1);
    
    char *p2 = buf+2;
    char filename[20]="";
    printf("请输入要下载的文件名>>>");
    scanf("%s",filename);
    getchar(); 
    strcpy(p2, filename);

    char *p3 = p2+strlen(p2)+1;
    strcpy(p3, "octet");

    int len = 4+strlen(p2) + strlen(p3);   //要发送的长度

    //向服务器发送请求
    if((sendto(cfd, buf, len, 0, (struct sockaddr*)&sin, sizeof(sin)))==-1)
    {
        perror("sendto error");
        return -1;
    }
    printf("下载请求已发送\n");
    socklen_t addrlen = sizeof(sin);
    int fd = -1;
    int res=0;
    unsigned short b_id = 0;//块编号
    char ack[4]="";
    //循环收发 
    while(1)
    {
        //客户端收取数据包
        bzero(buf,sizeof(buf));
        if((res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen))==-1)
        {
            perror("recv error");
            break;
        }
        //printf("收到的前四个字节为:[%d%d%d%d]\n",buf[0],buf[1],buf[2],buf[3]);
        
        b_id=ntohs(*(short *)(buf+2));
        if(buf[1]==3)
        {
            if((fd=open(filename,O_WRONLY|O_CREAT|O_APPEND,0664))==-1)
            {
                perror("open error");
                return -1;
            }
            
            
            //write(fd,buf+4,res-4);
            
            if(write(fd,buf+4,res-4)==-1)
            {
                perror("write all");
                break;
            }

            //ACK
            //发送ACK包
            bzero(ack,sizeof(ack));
            *(short*)ack=htons(4);
            *(short *)(ack + 2) = htons(b_id);
            if((sendto(cfd,ack,4,0,(struct sockaddr*)&sin,sizeof(sin)))==-1)
            {
                perror("sendto error");
                break;
            }
            if(res <516 )
            {
                puts("下载完成");
                break;
            }
            
        
        }
        if(buf[1]==5)
        {
            puts("error num");
            //char *err_id=(buf+3);
            //printf("errid=%d\n",*err_id);
            break;
        }

    }
    //puts("下载完成");
    close(fd);
    return 0;
}

int do_upload(int cfd,struct sockaddr_in sin)
{
    
    //向服务器发送上传请求

    char buf[516] = "";
	 //组装请求数据
    short *p1 = (short *)buf;
    *p1 = htons(2);
    
    char *p2 = buf+2;
    char filename[20]="";
    printf("请输入要上传的文件名>>>");
    scanf("%s",filename);
    getchar(); 
    strcpy(p2, filename);
    
    if(access(filename,F_OK)==-1)
    {
        perror("文件不存在");
        return -1;
    }

    char *p3 = p2+strlen(p2)+1;
    strcpy(p3, "octet");

    int len = 4+strlen(p2) + strlen(p3);   //要发送的长度

        //向服务器发送请求
    if((sendto(cfd, buf, len, 0, (struct sockaddr*)&sin, sizeof(sin)))==-1)
    {
        perror("sendto error");
        return -1;
    }
    printf("上传请求已发送\n");
    
    socklen_t addrlen = sizeof(sin);
    int fd = -1;
    int res=0;
    unsigned short b_id = 0;//块编号
    char ack[4]="";

    while(1)
    {
        //客户端收取数据包
        bzero(ack,sizeof(ack));
        if((recvfrom(cfd,ack,sizeof(ack),0,(struct sockaddr*)&sin,&addrlen))==-1)
        {
            perror("recv error");
            break;
        }
        printf("收到的前四个字节为:[%d%d%d%d]\n",ack[0],ack[1],ack[2],ack[3]);

        b_id=ntohs(*(short *)(ack+2));
        printf("b_id=%d\n",b_id);

        if(ack[1]==4)
        {
            
            puts("11");
            fd=open(filename,O_RDONLY);
            printf("fd=%d\n",fd);
            if(fd==-1)
            {
                perror("open error");
                break;
            }
            puts("aa");

            res=read(fd,buf+4,512);
            printf("res=%d\n",res);
            if(res==-1)
            {
                perror("read error");
                break;
            }

            puts("bb");
            bzero(buf,sizeof(buf));
            *(short*)buf=htons(3);
            *(short *)(buf + 2) = htons(b_id+1);
            if(sendto(cfd,buf,res+4,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
            {
                perror("sendto error");
                break;
            }
            puts("cc");
            if(res<512)
            {
                puts("上传成功");
                break;
            }

        }
        if(buf[1]==5)
        {
            puts("error num");
            char *err_id=(buf+3);
            printf("errid=%d\n",*err_id);
            break;
        }
    }
    close(fd);
    return 0;


}

int main(int argc, const char *argv[])
{
    //1、创建用于通信的套接字文件描述符
    int cfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(cfd == -1)
    {
        perror("socket error");
        return -1;
    }

    //2、绑定(可选)
    
    //3、填充服务器的地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(SER_PORT);
    sin.sin_addr.s_addr = inet_addr(SER_IP);

    char menu;

	//制作菜单框架
	while(1)
	{
		printf("\t\t====1.download====\n");
		printf("\t\t====2.upload  ====\n");
		printf("\t\t====0.exit    ====\n");
		
		printf("Please enter function options:");
		scanf("%c",&menu);
		while(getchar() != '\n');

		//对菜单选项多分支选择
		switch(menu)
		{
			case '1':    
				{
					do_download(cfd,sin);  //下载
				}
				break;
			case '2':
				{
					do_upload(cfd,sin);     //上传
				}
				break;
			case '0':
					exit(1);
			default:
				{
					printf("enter error!!!");
				}
		}
		printf("Enter any key to clear the screen:");
		while(getchar() != '\n');
		system("clear");
	}
    //5、关闭套接字
    close(cfd);


    return 0;
}

文章来源:https://blog.csdn.net/m0_56018621/article/details/135661488
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。