server.c服务器端,
#include<stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <linux/in.h> //sockaddr_in
#include <stdlib.h>
#include<string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define N 64
void server_list(int acceptfd);
void server_put(int acceptfd,char *filename);
void server_get(int acceptfd,char *filename);
int main(int argc, const char *argv[])
{
//1) socket(),创建套接字文件,用于连接
int sockfd,acceptfd;
ssize_t id;
pid_t pids;
if(argc<2)
{
printf("input a date %d,<端口号><IP>",argc);
exit(-1);
}
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
perror("socket failed.");
exit(-1);
}
printf("socket ok.\n");
//填充结构体sockaddr_in
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET; //填充协议 IPv4
serveraddr.sin_port = htons(atoi(argv[1])); // 端口号
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP任意的客户端都可以连接的服务器
socklen_t addrlen = sizeof(serveraddr);
//2) bind(),绑定,把socket()函数返回的文件描述符和IP、端口号进行绑定;
if(bind(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0)
{
perror("bind failed.");
exit(-1);
}
printf("bind ok.\n");
//3) listen(), (监听)将socket()返回的文件描述符的属æ§,由主动变为被动;
if(listen(sockfd,8) < 0)
{
perror("bind failed.");
exit(-1);
}
printf("listen ok.\n");
//4) accept(), 阻塞函数,阻塞等待å¢户端的连接请求,如果有客户端连接,
//则accept()函数返回的文件描述符和数返回,返回一个用于通信的套接字文件;
acceptfd = accept(sockfd,NULL,NULL);
printf("acceptfd ok.\n");
char buf[N] = {0};
char I;
while(1)
{
recv(acceptfd,buf,sizeof(buf),0);
switch(buf[0])
{
case 'l':server_list(acceptfd);break;
case 'p':server_put(acceptfd,buf+2);break;
case 'g':server_get(acceptfd,buf+2);break;
case 'q':exit(-1);break;
default:break;
}
}
return 0;
}
//读取目录的内容
void server_list(int acceptfd)
{
char buf1[N]={0};
DIR *dir;
struct dirent *dp;
struct stat *p;
dir=opendir(".");
while((dp=readdir(dir))!=NULL)//读取目录流
{
if(strncmp(dp->d_name,".",1)==0)//屏蔽隐藏的文件
continue;
stat(dp->d_name,p);//获取文件的属性
if(S_ISDIR(p->st_mode))
continue;
strcpy(buf1,dp->d_name);
send(acceptfd,buf1 ,sizeof(buf1),0);//将读取文件的名字发送给客户端
}
strncpy(buf1,"quit",4);
send(acceptfd,buf1,sizeof(buf1),0);
printf("server_ok\n");
}
//接受客户端上次的文件
void server_put(int acceptfd,char *filename)
{
char buf1[N]={0};
int fd;
int ss;
fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC, 0666);//创建的文件名字
while(1)
{
ss=recv(acceptfd,buf1,sizeof(buf1),0);//接受客户端发来的数据
if(strncmp(buf1,"quit\n",4)==0)
break;
write(fd,buf1,ss);
}
printf("server_ok\n");
}
//接收客户端的名字下载数据
void server_get(int acceptfd,char *filename)
{
char buf1[N]={0};
int ss;
int fd;
fd=open(filename,O_RDONLY);//以只读的方式打开文件
while(1)
{
ss=read(fd,buf1,sizeof(buf1));//读取文件的内容
if(ss==0)
{
break;
}
send(acceptfd,buf1,ss,0);
usleep(1000);//防止沾包,由于的传的太快,可能导致数据重复,所以进行延时
}
strcpy(buf1,"quit");
send(acceptfd,buf1,sizeof(buf1),0);
printf("server_ok\n");
}
client.c客户端
#include<stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include<math.h>
#include <linux/in.h>
#include<string.h>
#include<string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define N 64
void client_list(int sockfd);
void client_put(int sockfd,char *filename);
void client_get(int sockfd,char *filename);
int main(int argc,char *argv[])
{
//创建的一个socket描述符
struct sockaddr_in addrs;
int sockfd;
if(argc<3)
{
printf("input a date %d<端口><IP>",argc);
exit(-1);
}
sockfd=socket(AF_INET, SOCK_STREAM ,0);
char buf[N];
if(socket<0)
{
perror("socket\n");
exit(-1);
}
//填写sockaddr_in 结构体
bzero(&addrs,sizeof(addrs));//将结构体初始化为0
addrs.sin_family=AF_INET;//协议IPV4
addrs.sin_port=htons(atoi(argv[1]));//端口号将主机字节序到网络字节序
addrs.sin_addr.s_addr=inet_addr(argv[2]);将32位的IP地址(十进制)转化为二进制的IP地址网络字节
if(connect(sockfd, (struct sockaddr *)&addrs,sizeof(addrs))<0)
{
perror("connect\n");
exit(-1);
}
while(1)
{
printf("*******************************\n");
printf("************list***************\n");
printf("**********put filename*********\n");
printf("**********get filename*********\n");
printf("************quit***************\n");
printf("input>>>>:");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]='\0';
switch(buf[0])
{
case 'l':client_list(sockfd); break;
case 'p':client_put(sockfd,buf+4); break;
case 'g':client_get(sockfd,buf+4); break;
case 'q':exit(-1); break;
default:break;
}
}
return 0;
}
//显示目录的文件名字
void client_list(int sockfd)
{
char buf1[N]={0};
sprintf(buf1,"l");
send(sockfd,buf1,sizeof(buf1),0);
while(1)
{
//接受服务发过来的数据
recv(sockfd,buf1,sizeof(buf1),0);
if(strncmp(buf1,"quit",4)==0)
break;
printf("%s ",buf1);
}
printf("client_ok\n");
}
//上传文件
void client_put(int sockfd,char *filename)
{
char buf1[N]={0};
int ss;
int fd;
sprintf(buf1,"p %s",filename);
send(sockfd,buf1,sizeof(buf1),0);//进行数据的发送
fd=open(filename,O_RDONLY);//以只读的方式进行读取
while(1)
{
ss=read(fd,buf1,sizeof(buf1));//读文件里的内容
if(ss==0)
{
break;
}
send(sockfd,buf1,ss,0);
usleep(100000);
}
strcpy(buf1,"quit");
send(sockfd,buf1,sizeof(buf1),0);
printf("client_ok\n");
}
//下载文档
void client_get(int sockfd,char *filename)
{
char buf1[N]={0};
int fd;
int ss;
sprintf(buf1,"g %s",filename);
send(sockfd,buf1,sizeof(buf1),0);//进行数据的发送
fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666);//以读写的打开,并且写入数据*/
while(1)
{
ss=recv(sockfd,buf1,sizeof(buf1),0);
if(strncmp(buf1,"quit\n",4)==0)
{
break;
}
write(fd,buf1,ss);
}
printf("client_ok\n");
}