服务端server.c
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
//list:打开当前目录,循环读,判断是否是隐藏文件,是否是普通文件,是则发送文件名
void list(int acceptfd, char *buf, int size)
{
struct dirent *file = NULL;
struct stat st;
//打开当前目录
DIR *dir = opendir(".");
//循环读当前目录
while ((file = readdir(dir)) != NULL)
{
//获取读到文件的属性
stat(file->d_name, &st);
//判断是不是隐藏文件
if (file->d_name[0] == '.')
continue;
//判断是不是普通文件
if (S_ISREG(st.st_mode))
{
//把文件名发送给客户端
send(acceptfd, file->d_name, size, 0);
}
}
//发送结束标志
strcpy(buf, "LISTOK");
send(acceptfd, buf, size, 0);
closedir(dir);
}
//读打开文件,发送给客户端
void get(int acceptfd, char *buf, int size)
{
//只读打开文件
int fd = open(buf + 4, O_RDONLY);
if (fd < 0)
{
perror("open err.");
return;
}
int ret;
//循环读取文件内容
while (ret = read(fd, buf, size - 1))//为buf补结束标志'\0'
{
buf[ret] = '\0';
send(acceptfd, buf, size, 0);//发送读到的数据(包含'\0')
}
//发送结束标志
strcpy(buf, "send ok");
send(acceptfd, buf, size, 0);
close(fd);
}
//打开或新建文件,循环收并写入文件
void put(int acceptfd, char *buf, int size)
{
//只写,存在清空,不存在创建打开文件
int fd = open(buf + 4, O_WRONLY | O_TRUNC | O_CREAT, 0666);
if (fd < 0)
{
perror("open err.");
return;
}
//接收并写入
while (1)
{
//读取客户端发送的消息
if (recv(acceptfd, buf, size, 0) < 0)
{
perror("recv err.");
return;
}
//判断结束标志
if (strncmp(buf, "PUTOK", 5) == 0)
break;
//写实际读到的内容
write(fd, buf, strlen(buf));
}
close(fd);
}
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("please input %s <ip> <port>\n", argv[0]);
return -1;
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket err.");
return -1;
}
//填充相应结构体
struct sockaddr_in saddr, caddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(atoi(argv[1]));
saddr.sin_addr.s_addr = inet_addr("0.0.0.0");
socklen_t len = sizeof(caddr);
if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
perror("bind err.");
return -1;
}
if (listen(sockfd, 5) < 0)
{
perror("listen err.");
return -1;
}
while (1)
{
int acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
if (acceptfd < 0)
{
perror("accept err.");
return -1;
}
printf("client: ip=%s port=%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
char buf[128] = "0";
int ret = 0;
while (1)
{
ret = recv(acceptfd, buf, sizeof(buf), 0);
if (ret < 0)
{
perror("recv err.");
return -1;
}
else if (ret == 0)
{
printf("client exit.\n");
break;
}
else
{
if (strncmp(buf, "list", 4) == 0)
{
list(acceptfd, buf, sizeof(buf));
}
else if (strncmp(buf, "get ", 4) == 0)
{
get(acceptfd, buf, sizeof(buf));
}
if (strncmp(buf, "put ", 4) == 0)
{
put(acceptfd, buf, sizeof(buf));
}
}
}
close(acceptfd);
}
close(sockfd);
return 0;
}
客户端client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
void show(void)
{
printf("-----------------list-------------------\n");
printf("-----------------put filename-----------\n");
printf("-----------------get filename-----------\n");
printf("-----------------quit-------------------\n");
}
//从服务端接受文件名并打印
void list(int sockfd, char *buf, int size)
{
int ret = 0;
while (1)
{
//循环接收
ret = recv(sockfd, buf, size, 0);
if (ret < 0)
{
perror("recv err.");
return;
}
//判断是不是结束标志
if (strncmp(buf, "LISTOK", 6) == 0)
break;
printf("%s\n", buf);
}
}
//打开文件,循环读取写入文件
void get(int sockfd, char *buf, int size)
{
//只写,存在清空,不存在创建打开文件
int fd = open(buf + 4, O_WRONLY | O_TRUNC | O_CREAT, 0666);
if (fd < 0)
{
perror("open err.");
return ;
}
while (1)
{
//读取服务端发送的数据
if (recv(sockfd, buf, size, 0) < 0)
{
perror("recv err.");
return;
}
//判断结束标志
if (strncmp(buf, "send ok", 7) == 0)
break;
//写实际读到的个数
write(fd, buf, strlen(buf));
}
close(fd);
}
//读打开文件,然后循环发送给服务端
void put(int sockfd, char *buf, int size)
{
//只读打开文件
int fd = open(buf + 4, O_RDONLY);
if (fd < 0)
{
perror("open err.");
return;
}
//循环读 发送
int ret = 0;
//循环读文件
while (ret = read(fd, buf, size - 1))//为buf补'\0',所以-1为'\0'留位置
{
buf[ret] = '\0';
//发送读到的数据
send(sockfd, buf, size, 0);
}
//发送结束标志
strcpy(buf, "PUTOK");
send(sockfd, buf, size, 0);
close(fd);
}
int main(int argc, char const *argv[])
{
if (argc != 3)
{
printf("please input %s <ip> <port>\n", argv[0]);
return -1;
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket err.");
return -1;
}
//填充相应结构体
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(atoi(argv[2]));
saddr.sin_addr.s_addr = inet_addr(argv[1]);
if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
perror("connect err.");
return -1;
}
char buf[128] = "0";
while (1)
{
show();
printf("请输入命令:");
fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
send(sockfd, buf, sizeof(buf), 0);
if (strncmp(buf, "list", 4) == 0)
{
list(sockfd, buf, sizeof(buf));
}
else if (strncmp(buf, "get ", 4) == 0)
{
get(sockfd, buf, sizeof(buf));
}
else if (strncmp(buf, "put ", 4) == 0)
{
put(sockfd, buf, sizeof(buf));
}
else if (strncmp(buf, "quit", 4) == 0)
{
break;
}
}
close(sockfd);
return 0;
}