4.22基于UDP的练习

(1)UDP协议搭建流程服务器和客户端

服务器:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define ERRORLINE(msg) do{fprintf(stderr,"line:%d\n",__LINE__);perror(msg);}while(0);
#define IP "192.168.0.7"


int main(int argc, const char *argv[])
{
	//1.socket创建报式套接字
	int fd = socket(AF_INET,SOCK_DGRAM,0);
	if(fd<0)
	{
		ERRORLINE("socket");
		return -1;
	}
	
	//2.bind 绑定,ip地址和端口号
	struct sockaddr_in sin;
	sin.sin_family   = AF_INET;
	sin.sin_port     = htons(7777);
	sin.sin_addr.s_addr = inet_addr(IP);
	
	if(bind(fd,(struct sockaddr *)&sin,sizeof(sin))<0)
	{
		ERRORLINE("bind");
		return -1;
	}

/************************************/
	//建立connect函数连接对应交互端端口
	struct sockaddr_in din;
	din.sin_family   = AF_INET;
	din.sin_port     = htons(6666);
	din.sin_addr.s_addr = inet_addr("192.168.0.7");
	if(connect(fd,(struct sockaddr*)&din,sizeof(din))<0)
	{
		ERRORLINE("connect");
		return -1;
	}
	printf("连接成功\n");	

/************************************/
	//3.recvfrom 接受客户端信息
	char buf[128]={0};
	char suf[128]={0};
	struct sockaddr_in cin;
	socklen_t len = sizeof(cin);
	ssize_t n = 0;
	while(1)
	{
		bzero(buf,sizeof(buf));
		n = recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&len);
		if(n<0)
		{
			ERRORLINE("recvfrom");
			return -1;
		}

		printf("[%s : %d]:%s\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
		//4.sendto 发送机制
		

		strcpy(suf,"hello");
		n = sendto(fd,suf,sizeof(suf),0,(struct sockaddr *)&cin,sizeof(cin));
		if(n<0)
		{
			ERRORLINE("sendto");
			return -1;
		}

	}
	//5.关闭套接字
	close(fd);
	return 0;
}

客户端:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define ERRORLINE(msg) do{fprintf(stderr,"line:%d\n",__LINE__);perror(msg);}while(0);
#define IP "192.168.0.7"


int main(int argc, const char *argv[])
{
	//1.socket创建报式套接字
	int fd = socket(AF_INET,SOCK_DGRAM,0);
	if(fd<0)
	{
		ERRORLINE("socket");
		return -1;
	}
	
	//2.bind 绑定,ip地址和端口号
	struct sockaddr_in sin;
	sin.sin_family   = AF_INET;
	sin.sin_port     = htons(7777);
	sin.sin_addr.s_addr = inet_addr(IP);

/*	if(bind(fd,(struct sockaddr *)&sin,sizeof(sin))<0)
	{
		ERRORLINE("bind");
		return -1;
	}

*/	//3.recvfrom 接受客户端信息
	char buf[128]={0};
	char suf[128]={0};
	struct sockaddr_in cin;
	socklen_t len = sizeof(cin);
	ssize_t n = 0;
	while(1)
	{
		printf("请发送信息:");
		memset(suf,0,sizeof(suf));
		fgets(suf,sizeof(buf),stdin);
		suf[strlen(suf)-1]='\0';
			
		n = sendto(fd,suf,sizeof(suf),0,(struct sockaddr *)&sin,sizeof(sin));
		if(n<0)
		{
			ERRORLINE("sendto");
			return -1;
		}


		bzero(buf,sizeof(buf));
		n = recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&len);
		if(n<0)
		{
			ERRORLINE("recvfrom");
			return -1;
		}

		printf("[%s : %d]:%s\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
		//4.sendto 发送机制
		
	}
	//5.关闭套接字
	close(fd);
	return 0;
}

(2)基于UDP的上传和下载

下载:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>

#define ERRORLINE(msg) do{fprintf(stderr,"line:%d\n",__LINE__);perror(msg);}while(0);
#define IP "192.168.0.114"

int main(int argc, const char *argv[])
{
	int file_fd;
	//1.创建套接字
	
	int fd = socket(AF_INET,SOCK_DGRAM,0);
	if(fd<0)
	{
		ERRORLINE("socket");
		return -1;
	}
	//2.确定服务器端口
	struct sockaddr_in sin;
	sin.sin_family   = AF_INET;
	sin.sin_port     = htons(69);
	sin.sin_addr.s_addr = inet_addr(IP);

/*	char buf[516] = {0};
	short *p =  (short *)buf;

	char *p1 = buf+2;
	char *p2 = buf+7;
	char *p3 = buf+8;
	char *p4 = buf+13;
	*p=htons(1);
	strcpy(p1,"5.png");
	*p2 = 0;
	strcpy(p3,"octet");
	*p4 = 0;
*/
	//4.实现功能
	printf("****1下载****\n");
	printf("****2上传****\n");
	printf("****3待机****\n");
	printf("请选择功能:");
	int choose = 0;
	char a = 0;
	char arr[64] = {0};
	scanf("%d",&choose);
	getchar();
	while(1)
	{
		if(choose == 1)
		{
			a = 0x01;
			printf("请输入要下载的文件名:");
			fgets(arr,sizeof(arr),stdin);
			arr[strlen(arr)-1]='\0';
			
			//建立读写文件接受数据
			file_fd = open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0666);
			if(file_fd<0)
			{
				ERRORLINE("open");
				return -1;
			}
			break;
		}
		else if(choose == 2)
		{
			a = 0x02;
			printf("请输入要上传的文件名:");	
			fgets(arr,sizeof(arr),stdin);
			arr[strlen(arr)-1]='\0';

			file_fd = open(argv[1],O_RDONLY);
			if(file_fd<0)
			{
				ERRORLINE("open");
				return -1;
			}

			break;
		}
	}
	//组建发送读写指令协议包
	char buf[516] = {0};
	int size = sprintf(buf,"%c%c%s%c%s%c",0x00,a,arr,0,"octet",0);


	//遍历组装的包
	/*
	   for(int i=0; i<size; i++)
	   {
	   printf("buf[%d]:%c | %d\n",i,buf[i],buf[i]);
	   }
	 */


	//发送下载/上传请求数据包
	int n = 0;
	n = sendto(fd,buf,size,0,(struct sockaddr *)&sin,sizeof(sin));
	if(n<0)
	{
		ERRORLINE("sendto");
		return -1;
	}

	struct sockaddr_in cin;	//地址结构体等待接收返回信息
	socklen_t len = sizeof(cin);
	pid_t pid = fork();
	if(pid<0)
	{
		ERRORLINE("pid");
		return -1;
	}
	else if(pid == 0)
	{

		while(1)
		{
			bzero(buf,sizeof(buf));
			n=recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&len);
			if(n<0)
			{
				ERRORLINE("recvfrom");
				return -1;
			}

			if(n<512)
			{
				exit(EXIT_SUCCESS);
			}
			//保存2字节的块编号或差错码
			char buf_2 = buf[2];
			char buf_3 = buf[3];

		/*	for(int i=0; i<n; i++)
			{
				printf("buf[%d]:%c | %d\n",i,buf[i],buf[i]);
			}
		*/
	//		printf("%d\n",ntohs(cin.sin_port));
			if(buf[1] != 3)
			{
				ERRORLINE("recvfrom");
				printf("差错码:%c%c\n",buf[1],buf[2]);
				for(int j = 4; buf[j] != '\0'; j++)
				{
					printf("%c",buf[j]);
				}
				fflush(stdout);
				exit(0);
			}
			else
			{
				for(int i=4;i<n;i++)         
				{
					write(file_fd,&buf[i],1);
				}
			}
	
			bzero(buf,sizeof(buf));
			size = sprintf(buf,"%c%c%c%c",0x00,0x04,buf_2,buf_3);

/*			for(int i=0; i<size; i++)
			{
				printf("buf[%d]:%c | %d\n",i,buf[i],buf[i]);
			}
*/
			n = sendto(fd,buf,size,0,(struct sockaddr*)&cin,sizeof(cin));
			if(n<0)
			{
				ERRORLINE("sendto");
				return -1;
			}			
		}
		
	}
	else
	{

		waitpid(-1,NULL,0);
		printf("下载完成\n");
	}	
	close(file_fd);
	close(fd);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值