0813网络编程day3

 

 

服务器 

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

//打印错误信息的宏函数
#define ERR_MSG(msg) do{\
    fprintf(stderr,"__%d__",__LINE__);\
    perror(msg);\
}while(0)

#define PORT 8888             //1024~49151
#define IP "192.168.31.14" //服务器ip,用ifconfig查看


int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd=socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("create socket success\n");

	//允许端口快速复用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}

	//填充地址信息结构体,真实的地址信息结构体与协议族相关
	//AF_INET,所以详情请看man 7 ip
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;
	sin.sin_port        = htons(PORT);  //网络字节序的端口号
	sin.sin_addr.s_addr = inet_addr(IP);    //网络字节序的IP地址


	//将地址信息结构体绑定到套接字上
	if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("bind");                                        
		return -1;
	}
	printf("bind success\n");



	char buf[128]="";
	char rcv_demand[128]="";
	ssize_t res=0;
	int newfd;
	struct sockaddr_in cin;
	while(1)
	{
		if(res==0)
		{
			//将套接字设置为被动监听状态,让内核去监听是否有客户端连接;
			if(listen(sfd, 10) < 0)
			{
				ERR_MSG("listen");
				return -1;                                                
			}
			printf("正在查询有无端口连接\n");


			socklen_t addrlen = sizeof(cin);
			//从已完成连接的队列头中,取出一个客户端的信息,创建生成一个新的套接字文件描述符,
			//该文件描述符才是与客户端通信的文件描述符!!!
			newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);
			if(newfd < 0)
			{
				perror("accept");
				return -1;
			}
			printf("连接完成\n");	
		}

		
		bzero(rcv_demand,sizeof(rcv_demand));


		//循环接收是下载还是上传
		res=recv(newfd,rcv_demand,sizeof(rcv_demand),0);
		if(res<0)
		{
			ERR_MSG("recv");
			return -1;
		}
		else if(0==res)
		{
			printf("端口%d已关闭\n",ntohs(cin.sin_port));
			continue;
		}

		if(strcmp(rcv_demand,"find")==0)
		{
			DIR* dp=opendir("./");
			if(NULL==dp)
			{
				ERR_MSG("opendir");
				return -1;
			}

			struct dirent*rp =NULL;
			while(1)
			{
				bzero(buf,sizeof(buf));
				rp=readdir(dp);
				if(NULL==rp)
				{
					if(0==errno)
					{
						printf("目录读取完毕\n");
						strcpy(buf,"end of catalogue");
						send(newfd,buf,sizeof(buf),0);
						break;
					}
					else
					{
						ERR_MSG("readdir");
						return -1;
					}
				}
				if(rp->d_name[0]=='.')
					continue;	
				strcpy(buf,rp->d_name);
				send(newfd,buf,sizeof(buf),0);
			}
		}
		//1下载
		else if(rcv_demand[0]=='1')
		{
			printf("开始下载\n");
			//打开要被下载的文件,如不存在则询问
			FILE *fp=fopen(rcv_demand+1,"r");
			if(NULL==fp)
			{
				ERR_MSG("fopen");
				return -1;
			}

			size_t res2;
			while(1)
			{
				bzero(buf,sizeof(buf));
				res2=fread(buf,1,sizeof(buf),fp);
				if(res2<0)
				{
					ERR_MSG("fread");
					return -1;
				}
				else if(res2<sizeof(buf))
				{
					send(newfd,buf,res2,0);
					printf("下载完成\n");
					break;
				}
				if(send(newfd,buf,sizeof(buf),0)<0)
				{
					ERR_MSG("fread");
					return -1;
				}
			}
			fclose(fp);
		}
		//2上传
		else if(rcv_demand[0]=='2')
		{
			printf("开始上传\n");

			//以写权限创建并打开文件,如已存在则询问
			FILE *fp2=fopen(rcv_demand+1,"w");

			ssize_t res_recv=0;
			ssize_t res_fwrite=0;
			while(1)
			{
				bzero(buf,sizeof(buf));

				res_recv=recv(newfd,buf,sizeof(buf),0);
					if(res_recv<0)
					{
						ERR_MSG("recv");
						return -1;
					}

				res_fwrite=fwrite(buf,1,res_recv,fp2);
				if(res_fwrite<0)
				{
					ERR_MSG("fwrite");
					return -1;
				}
				else if(res_fwrite<sizeof(buf))
				{
					printf("上传完成\n");
					break;
				}
			}
			fclose(fp2);
		}
	}

	close(sfd);
	close(newfd);
	return 0;
}

客户端 

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

//打印错误信息的宏函数
#define ERR_MSG(msg) do{\
    fprintf(stderr,"__%d__",__LINE__);\
    perror(msg);\
}while(0)

#define PORT 6666            //1024~49151
#define IP "192.168.31.14" //服务器ip,用ifconfig查看

int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd=socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("create socket success\n");

	//允许端口快速复用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}



	//填充地址信息结构体,真实的地址信息结构体与协议族相关
	//AF_INET,所以详情请看man 7 ip
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;
	sin.sin_port        = htons(PORT);  //网络字节序的端口号
	sin.sin_addr.s_addr = inet_addr(IP);    //网络字节序的IP地址


	//将地址信息结构体绑定到套接字上
	if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("bind");                                        
		return -1;
	}
	printf("bind success\n");

	struct sockaddr_in cin;
	cin.sin_family      = AF_INET;
	cin.sin_port        = htons(8888);  //网络字节序的端口号
	cin.sin_addr.s_addr = inet_addr(IP);    //网络字节序的IP地址


	//连接到服务器
	if(connect(sfd,(struct sockaddr *)&cin,sizeof(cin))<0)
	{
		ERR_MSG("connect");
		return -1;
	}
	
	char buf[128]="";
	char snd_demand[128]="";
	char download_name[128]="";
	char uploading_name[128]="";

	while(1)
	{
		printf("请输入您要下载还是上传,查看请输入find,退出请输入quit\n");
		bzero(snd_demand,sizeof(snd_demand));
		fgets(snd_demand,sizeof(snd_demand),stdin);
		snd_demand[strlen(snd_demand)-1]=0;

		//如果输入quit,则退出
		if(strcmp("quit",snd_demand)==0)
			exit(0);
		else if(strcmp("find",snd_demand)==0)
		{
			bzero(buf,sizeof(buf));
			send(sfd,snd_demand,sizeof(snd_demand),0);
			while(1)
			{
				recv(sfd,buf,sizeof(buf),0);
				if(strcmp(buf,"end of catalogue")==0)
				{
					break;
				}
				printf("%s\n",buf);
			}
		}
		//输入1,下载
		else if(snd_demand[0]=='1')
		{
			printf("请输入您要下载的文件名\n");
		}
		//输入2,,上传
		else if(snd_demand[0]=='2')
		{
			printf("请输入您要上传的文件名\n");
		}

		//如果下载,循环接收
		if(snd_demand[0]=='1')
		{
			//输入要下载(上传)的文件名
			fgets(snd_demand+1,sizeof(snd_demand)-1,stdin);
			snd_demand[strlen(snd_demand)-1]=0;

			printf("请输入你下载到客户端之后的文件名\n");
			bzero(download_name,sizeof(download_name));
			fgets(download_name,sizeof(download_name),stdin);
			download_name[strlen(download_name)-1]=0;
			
			//发送(下载/上传)文件名
			if(send(sfd,snd_demand,sizeof(snd_demand),0)<0)
			{
				ERR_MSG("send");
				return -1;
			}

			//打开要下载过来的文件名
			FILE *fp=fopen(download_name,"w");
			if(NULL==fp)
			{
				ERR_MSG("fopen");
				return -1;
			}
			
			//接收的字节数
			ssize_t res_recv=0;
			//写入文件的字节数
			ssize_t res_fwrite=0;
			while(1)
			{
				bzero(buf,sizeof(buf));
				//接收字符串
				res_recv=recv(sfd,buf,sizeof(buf),0);
				if(res_recv<0)
				{
					ERR_MSG("recv");
					return -1;
				}
				res_fwrite=fwrite(buf,1,res_recv,fp);
				if(res_fwrite<0)
				{
					ERR_MSG("fwrite");
					return -1;
				}
				else if(res_fwrite<sizeof(buf))
				{
					printf("下载完成\n");
					break;
				}
			}
			fclose(fp);
		}
		//如果上传,循环发送
		else if(snd_demand[0]=='2')
		{
			//输入要下载(上传)的文件名
			bzero(uploading_name,sizeof(uploading_name));
			fgets(uploading_name,sizeof(uploading_name),stdin);
			uploading_name[strlen(uploading_name)-1]=0;

			printf("请输入您上传到服务器之后的文件名\n");
			fgets(snd_demand+1,sizeof(snd_demand)-1,stdin);
			snd_demand[strlen(snd_demand)-1]=0;

			//发送(下载/上传)文件名
			if(send(sfd,snd_demand,sizeof(snd_demand),0)<0)
			{
				ERR_MSG("send");
				return -1;
			}

			//打开要上传到服务器的文件名
			FILE *fp2=fopen(uploading_name,"r");
			if(NULL==fp2)
			{
				ERR_MSG("fopen");
				return -1;
			}

			size_t res2;

			while(1)
			{
				bzero(buf,sizeof(buf));
				res2=fread(buf,1,sizeof(buf),fp2);
				if(res2<0)
				{
					ERR_MSG("fread");
					return -1;
				}
				else if(res2<sizeof(buf))
				{
					send(sfd,buf,res2,0);
					printf("上传完成\n");
					break;
				}
				if(send(sfd,buf,sizeof(buf),0)<0)
				{
					ERR_MSG("send");
					return -1;
				}

			}
			fclose(fp2);
		}
	}
	close(sfd);
	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值