11月21日作业

流式域服务器


#include <myhd.h>
#define PORT 8888     //端口号
#define IP "192.168.114.13"  //IP地址
int main(int argc, const char *argv[])
{
	//1、创建用于接受链接的套接字
	int sfd=socket(AF_UNIX,SOCK_STREAM,0);
	if(sfd==-1)
	{
		perror("socket error");
		return -1;
	}
	printf("socket success sfd=%d\n",sfd);

	//设置端口号快速重用
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
	{
		perror("setsockopt error");
		return -1;
	}
	printf("设置端口快速重用成功\n");

	//判断套接字文件是否存在
	if(access("mySock",F_OK)==0)
	{
		if(unlink("./mySock")!=0)
		{
			perror("unlink error");
			return -1;
		}
	}
	//2、绑定IP地址和端口号
	//2.1、填充要绑定的地址信息结构体
	struct sockaddr_un sun;
	sun.sun_family=AF_UNIX;
	strcpy(sun.sun_path,"mySock");
	//2.2、绑定
	if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
	{
		perror("bind error");
		return -1;
	}
	printf("bing success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
	//3、将套接字设置成被动监听状态
	if(listen(sfd,128)==-1)
	{
		perror("listen error");
		return -1;
	}
	printf("listen success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
	//4、阻塞等待客户端链接请求,如果有新的客户端连接,则创建一个新的用于通信的套接字
	//4.1、定义客户端地址信息结构体
	struct sockaddr_un cun;   //客户端地址信息结构体
	cun.sun_family=AF_UNIX;
	socklen_t socklen=sizeof(cun);  //客户端地址信息大小
	//4.2、阻塞接收客户端的连接请求,并且获取客户端的地址信息
	int newfd=accept(sfd,(struct sockaddr*)&cun,&socklen);
	if(newfd==-1)
	{
		perror("accept error");
		return -1;
	}
	printf("accept success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
	//5、收发数据使用newfd完成通信
	char buf[128]="";
	while(1)
	{
		//清空字符串
		bzero(buf,sizeof(buf));
		//read(newfd,buf,sizeof(buf));  //从套接字中读取客户端发来的消息
		int res=recv(newfd,buf,sizeof(buf),0);
		//判断收到的结果
		if(res==0)
		{
			printf("客户端已经下线\n");
			break;
		}
		else if(res<0)
		{
			perror("recv error");
			return -1;
		}
		printf("[%s]:%s\n",cun.sun_path,buf);
		//将读取的信息加上一些字符发送回去
		strcat(buf,"*_*");
		//write(newfd,buf,sizeof(buf));
		send(newfd,buf,sizeof(buf),0);
		printf("发送成功\n");
	}
	//6、关闭所有套接字
	close(sfd);
	close(newfd);
	return 0;
}

流式域客户端


#include <myhd.h>
int main(int argc, const char *argv[])
{
	//1、创建客户端用于通信的套接字
	int cfd=socket(AF_UNIX,SOCK_STREAM,0);
	if(cfd==-1)
	{
		perror("socket error");
		return -1;
	}
	printf("cfd=%d\n",cfd);
	//判断套接字文件是否存在
	if(access("cliSock",F_OK)==0)
	{
		if(unlink("./cliSock")!=0)
		{
			perror("unlink error");
			return -1;
		}
	}
	//2、绑定
	//2.1、填充地址信息结构体
	struct sockaddr_un cun;
	cun.sun_family=AF_UNIX;  
	strcpy(cun.sun_path,"cliSock");
	//2.2、绑定工作
	if(bind(cfd,(struct sockaddr*)&cun,sizeof(cun))==-1)
	{
		perror("bind error");
		return -1;
	}
	printf("bind success\n");
	//3、连接服务器
	//3.1、填充服务器地址信息结构体
	struct sockaddr_un sun;
	sun.sun_family=AF_UNIX;  //使用ipv4通信
	strcpy(sun.sun_path,"mySock");
	//3.2、连接服务器
	if(connect(cfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
	{
		perror("connect error");
		return -1;
	}
	printf("connect success\n");
	//4、收发数据
	char buf[128]="";
	char rbuf[128]="";
	while(1)
	{
		bzero(buf,sizeof(buf));
		bzero(rbuf,sizeof(rbuf));
		printf("请输入:");
		fgets(buf,sizeof(buf),stdin);  //从标准输入中读取数据
		buf[strlen(buf)-1]='\0';
		//将数据发送给服务器
		send(cfd,buf,sizeof(buf),0);
		//输入quit退出
		if(strcmp(buf,"quit")==0)
		{
			break;
		}
		//接收服务器发送来的消息
		int res=recv(cfd,rbuf,sizeof(rbuf),0);
		if(res==0)
		{
			printf("服务器已经关闭\n");
			break;
		}
		printf("rbuf=%s\n",rbuf);
	}
	//5、关闭客户端套接字文件
	close(cfd);
	return 0;
}

报式域服务器

#include <myhd.h>

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

	//设置端口号快速重用
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
	{
		perror("setsockopt error");
		return -1;
	}
	printf("设置端口快速重用成功\n");

	//判断套接字文件是否存在
	if(access("mySock",F_OK)==0)
	{
		if(unlink("./mySock")!=0)
		{
			perror("unlink error");
			return -1;
		}
	}
	//2、绑定IP地址和端口号
	//2.1、填充要绑定的地址信息结构体
	struct sockaddr_un sun;
	sun.sun_family=AF_UNIX;
	strcpy(sun.sun_path,"mySock");
	//2.2、绑定
	if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
	{
		perror("bind error");
		return -1;
	}
	printf("bing success _%d_%s_%s_\n",__LINE__,__FILE__,__func__);
	
	//4、阻塞等待客户端链接请求,如果有新的客户端连接,则创建一个新的用于通信的套接字
	//4.1、定义客户端地址信息结构体
	struct sockaddr_un cun;   //客户端地址信息结构体
	cun.sun_family=AF_UNIX;
	socklen_t socklen=sizeof(cun);  //客户端地址信息大小
	//5、收发数据使用newfd完成通信
	char buf[128]="";
	while(1)
	{
		//清空字符串
		bzero(buf,sizeof(buf));
		//read(newfd,buf,sizeof(buf));  //从套接字中读取客户端发来的消息
		int res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,&socklen);
		//判断收到的结果
		if(res==0)
		{
			printf("客户端已经下线\n");
			break;
		}
		else if(res<0)
		{
			perror("recv error");
			return -1;
		}
		printf("[%s]:%s\n",cun.sun_path,buf);
		//将读取的信息加上一些字符发送回去
		strcat(buf,"*_*");
		//write(newfd,buf,sizeof(buf));
		sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,sizeof(cun));
		printf("发送成功\n");
	}
	//6、关闭所有套接字
	close(sfd);
	return 0;
}

报式域客户端

#include <myhd.h>
int main(int argc, const char *argv[])
{
	//1、创建客户端用于通信的套接字
	int cfd=socket(AF_UNIX,SOCK_DGRAM,0);
	if(cfd==-1)
	{
		perror("socket error");
		return -1;
	}
	printf("cfd=%d\n",cfd);
	//判断套接字文件是否存在
	if(access("cliSock",F_OK)==0)
	{
		if(unlink("./cliSock")!=0)
		{
			perror("unlink error");
			return -1;
		}
	}
	//2、绑定
	//2.1、填充地址信息结构体
	struct sockaddr_un sun;
	sun.sun_family=AF_UNIX;  
	strcpy(sun.sun_path,"cliSock");
	//2.2、绑定工作
	if(bind(cfd,(struct sockaddr*)&sun,sizeof(sun))==-1)
	{
		perror("bind error");
		return -1;
	}
	printf("bind success\n");

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

	//4、收发数据
	char buf[128]="";
	char rbuf[128]="";
	while(1)
	{
		bzero(buf,sizeof(buf));
		bzero(rbuf,sizeof(rbuf));
		printf("请输入:");
		fgets(buf,sizeof(buf),stdin);  //从标准输入中读取数据
		buf[strlen(buf)-1]='\0';
		//将数据发送给服务器
		sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,sizeof(cun));
		//输入quit退出
		if(strcmp(buf,"quit")==0)
		{
			break;
		}
		//接收服务器发送来的消息
		int res=recvfrom(cfd,rbuf,sizeof(rbuf),0,NULL,NULL);
		if(res==0)
		{
			printf("服务器已经关闭\n");
			break;
		}
		printf("rbuf=%s\n",rbuf);
	}
	//5、关闭客户端套接字文件
	close(cfd);
	return 0;
}

tftp

#include <myhd.h>

//实现下载功能
int Do_download(int cfd,struct sockaddr_in sin)
{
	socklen_t socklen=sizeof(sin);
	//定义变量存储下载请求包
	char buf[516]="";
	//定义变量存储文件名
	char fileName[40]="";

	printf("请输入文件名:");
	scanf("%s",fileName);
	getchar();

	//组装请求包
	short *p1=(short*)buf;
	*p1=htons(1);  //1下载/2上传

	char *p2=buf+2;  //文件名段
	strcpy(p2,fileName);
	//printf("strlen(p2)=%lx\n",strlen(p2));

	char *p4=p2+strlen(p2)+1;  //模式段
	strcpy(p4,"octet");

	int size=4+strlen(p2)+strlen(p4);  //要发送数据的大小
	
	//向服务器发送下载请求
	if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("sendto error");
		return -1;
	}
	printf("请求成功\n");

	int wfd;
	if((wfd=open("./text1.txt",O_RDWR|O_APPEND|O_CREAT,0664))==-1)
	{
		perror("open error");
		return -1;
	}
	//循环接收回复服务器发来的消息
	while(1)
	{
		//接收数据包
		bzero(buf,sizeof(buf));
		if(recvfrom(cfd,buf,size,0,(struct sockaddr*)&sin,&socklen)==-1)
		{
			perror("recvfrom error");
			return -1;
		}

		//拆分数据包
		//操作码段
		short *q1=(short *)buf;
		//得到块编号
		short *q2=q1+2;  //*q2为块编号
		//数据段为0则下载完成退出循环
		char *q3=buf+4;
		//char q3[512]="";
		//int i=4;
		//int j=0;
		//while(buf[i]!='\0'||i<=516)
		//{
	        //	q3[j]=buf[i];
		//	i++;j++;
		//}
		
		if(strlen(q3)<=0)
		{
			break;
		}

			printf("strlen(q3)=%lx\n",strlen(q3));
		
		write(wfd,q3,strlen(q3));
		//向服务器发送ACK
		bzero(buf,sizeof(buf));
		//ACK组装
		short *j1=(short *)buf;
		*j1=htons(4);  //ACK
		//块编号段
		short *j2=(short *)buf+2;
		*j2=*q2;

		//向服务器发送ACK
		if(sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
		{
			perror("ACK sendto error");
			return -1;
		}
		printf("ACK返回成功\n");
	}
}

int Do_upload(int cfd,struct sockaddr_in sin)
{
	socklen_t socklen=sizeof(sin);
	//定义变量存储上传请求包
	char buf[516]="";
	//定义变量存储文件名
	char fileName[40]="";

	printf("请输入文件名:");
	scanf("%s",fileName);
	getchar();

	//组装请求包
	short *p1=(short*)buf;
	*p1=htons(2);  //1下载/2上传

	char *p2=buf+2;  //文件名段
	strcpy(p2,fileName);

	char *p4=p2+strlen(p2)+1;  //模式段
	strcpy(p4,"octet");

	int size=4+strlen(p2)+strlen(p4);  //要发送数据的大小
	
	//向服务器发送下载请求
	if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
	{
		perror("sendto error");
		return -1;
	}
	printf("请求成功\n");

	int rfd;
	if((rfd=open(fileName,O_RDONLY))==-1)
	{
		perror("open error");
		return -1;
	}

	//循环接收回复服务器发来的消息
	while(1)
	{
		//接收服务器发送的ACK
		bzero(buf,sizeof(buf));

		//接收服务器发送的ACK
		if(recvfrom(cfd,buf,4,0,(struct sockaddr*)&sin,&socklen)==-1)
		{
			perror("ACK recvfrom error");
			return -1;
		}
		printf("ACK返回成功\n");
		
		//ACK组装
		short *j1=(short *)buf;
		//块编号段
		short *j2=(short *)buf+2;
		
		//上传数据包
		bzero(buf,sizeof(buf));

		//拆分数据包
		//操作码段
		short *q1=(short *)buf;
		*q1=htons(3);
		//得到块编号
		short *q2=q1+2;  //*q2为块编号
		*q2=*j2;
		//数据段为0则下载完成退出循环
		char *q3=buf+4;
		if(strlen(q3)<=0)
		{
			break;
		}
		read(rfd,q3,sizeof(q3));
		if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
		{
			perror("sendto error");
			return -1;
		}

	}
}

int main(int argc, const char *argv[])
{
	if(argc!=2)
	{
		printf("input error\n");
		return -1;
	}

	//创建用于接受连接的套接字
	int cfd=socket(AF_INET,SOCK_DGRAM,0);
	if(cfd==-1)
	{
		perror("socket error");
		return -1;
	}
	printf("socket success cfd=%d\n",cfd);

	//填充要绑定的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(69);
	sin.sin_addr.s_addr=inet_addr(argv[1]);

	int mune=-1;
	while(1)
	{
		system("clear");
		printf("\t\t=====1、下载=====\n");
		printf("\t\t=====2、上传=====\n");
		printf("\t\t=====0、退出=====\n");

		printf("请输入功能:");
		scanf("%d",&mune);
		getchar();

		switch(mune)
		{
			case 1:Do_download(cfd,sin);break;
			case 2:Do_upload(cfd,sin);break;
			case 0:goto POS;
			default:printf("输入错误,请输入1、2、0\n");
		}

		//阻塞
		printf("按回车键清空\n");
		while(getchar()!='\n');
	}
POS:
	//关闭套接字
	close(cfd);

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值