1》客户端代码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*list:客户端输入list------》把list发送给服务器-------》接收list---》判断是否为list----》目录操作(循环读目录文件)--------》判断是否为普通文件-----》如果是普通文件就发送给客户端------》发送一个结束“end”的标志----------》客户端循环接收普通文件并打印到终端显示
put filename:客户端输入put 文件名---》把put 文件名发送给服务器---》接收put 文件名---》判断是否为put -----》(cp:源文件再客户端所在路径下,目标文件在服务器所在路径下)客户端循环读源文件发送给服务器,服务器循环接收写到目标文件里--------》发送一个结束“end”的标志*/
char buf[128] = {0};
/*帮助菜单*/
void Help()
{
printf("**************list**************\n");
printf("**********put filename***********\n");
printf("**********get filename***********\n");
printf("**************quit**************\n");
}
// 获取服务器目录下文件
void list(int acceptfd)
{
int ret;
// 循环接收服务器发送的目录信息
while (1)
{
memset(buf, 0, sizeof(buf));
ret = recv(acceptfd, buf, sizeof(buf), 0);
if (ret < 0)
{
perror("recv err");
return;
}
if (strcmp(buf, "end") == 0) // 服务器发送结束
break;
else
printf("%s ", buf);
}
printf("\n");
return;
}
/*上传数据*/
void put(int acceptfd, char *p)
{
int fd;
fd = open(p + 4, O_RDONLY);
int n;
while (n = read(fd, buf, 127))
{
send(acceptfd, buf, sizeof(buf), 0);
memset(buf,0,sizeof(buf));
}
send(acceptfd, "end", 128, 0);
close(fd);
return;
}
/*下载数据*/
int get(int acceptfd, char *p)
{
int fd;
fd = open(p + 4, O_WRONLY | O_CREAT | O_TRUNC, 0755);
if (fd < 0)
{
perror("open err\n");
return -1;
}
while (1)
{
recv(acceptfd, buf, sizeof(buf), 0);
if (strcmp(buf, "end") == 0)
break;
write(fd, buf, strlen(buf));
memset(buf,0,sizeof(buf));
}
close(fd);
return 0;
}
int main(int argc, char const *argv[])
{
if (argc != 3)
{
perror("argc err\n");
return -1;
}
// 1.创建套接字(socket)------------》有手机
int clientfd = socket(AF_INET, SOCK_STREAM, 0);
if (clientfd < 0)
{
perror("socket err\n");
return -1;
}
printf("%d\n", clientfd);
// 2.指定(服务器)网络信息--------》有对方的号码
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]);
// 3.连接(connect)-------------------》拨打电话
if (connect(clientfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
perror("connect err\n");
return -1;
}
printf("connect ok\n");
// 4.接收发送消息(recv send)---》通话
while (1)
{
Help();
fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n')
{
buf[strlen(buf) - 1] = '\0';
}
send(clientfd, buf, sizeof(buf), 0);
// fgets(buf, sizeof(buf), stdin);
if (strcmp("list", buf) == 0) // 接收服务器发来的文件名
{
list(clientfd);
}
else if (strncmp(buf, "put ", 4) == 0)
{
put(clientfd, buf);
}
else if (strncmp(buf, "get ", 4) == 0)
{
get(clientfd, buf);
}
else if (strcmp(buf, "quit") == 0)
{
break;
}
// write(socketfd, buf, sizeof(buf));
}
// 5.关闭套接字(close)------------》挂电话
close(clientfd);
return 0;
}
2》服务器代码
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
char buf[128] = {0};
/*获取服务器目录*/
void list(int acceptfd)
{
DIR *dir;
dir = opendir("./"); // 打开服务器所在目录
struct dirent *list; // 定义指向目录文件的指针
struct stat st; // 保存文件属性
// 循环读取目录下的文件
while ((list = readdir(dir)) != NULL)
{
stat(list->d_name, &st); // 获取文件类型
if ((st.st_mode & __S_IFMT) == __S_IFREG) // 判断是否为普通文件
{
// 把文件名字发送给客户端
send(acceptfd, list->d_name, sizeof(list->d_name), 0);
}
}
send(acceptfd, "end", sizeof(buf), 0); // 向客户端发送结束标志
}
/*上传数据*/
int putf(int acceptfd, char *p)
{
int fd;
fd = open(p + 4, O_WRONLY | O_CREAT | O_TRUNC, 0755);
if (fd < 0)
{
perror("open err\n");
return -1;
}
while (1)
{
recv(acceptfd, buf, sizeof(buf), 0);
if (strcmp(buf, "end") == 0)
break;
write(fd, buf, strlen(buf));
memset(buf,0,sizeof(buf));
}
close(fd);
return 0;
}
/*下载数据*/
void getf(int acceptfd, char *p)
{
int fd;
fd = open(p + 4, O_RDONLY);
int n;
while (n = read(fd, buf, 127))
{
send(acceptfd, buf, sizeof(buf), 0);
memset(buf,0,sizeof(buf));
}
send(acceptfd, "end", 128, 0);
close(fd);
return;
}
int main(int argc, char const *argv[])
{
if (argc != 2)
{
perror("argc err\n");
return -1;
}
// 1.创建套接字(socket)---------------》有手机
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
if (socketfd < 0)
{
perror("socket err\n");
return -1;
}
printf("socketfd: %d\n", socketfd);
// 2.指定(自己)网络信息--------------------》有号码
// struct sockaddr_in
// {
// sa_family_t sin_family; /* address family: AF_INET */
// in_port_t sin_port; /* port in network byte order */
// struct in_addr sin_addr; /* internet address */
// };
// /* Internet address. */
// struct in_addr
// {
// uint32_t s_addr; /* address in network byte order */
// };
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");
// saddr.sin_addr.s_addr = INADDR_ANY;
// 3.绑定套接字(bind)------------------》绑定手机(插卡)
if (bind(socketfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
perror("bind err\n");
return -1;
}
printf("bind ok\n");
// 4.监听套接字(listen)-----------------》待机
if (listen(socketfd, 6) < 0)
{
perror("listen err\n");
return -1;
}
printf("listen ok\n");
// 5.接收客户端连接连接请求(accept)--》接电话
while (1)
{
int len = sizeof(caddr);
int acceptfd = accept(socketfd, (struct sockaddr *)&caddr, &len);
if (acceptfd < 0)
{
perror("accept err\n");
return -1;
}
printf("acceptfd: %d\n", acceptfd);
printf("port: %d ip: %s\n", ntohs(caddr.sin_port), inet_ntoa(caddr.sin_addr));
// 6.接收、发送数据(recv send)---》通话
int ret;
while (1)
{
memset(buf, 0, sizeof(buf));
ret = recv(acceptfd, buf, sizeof(buf), 0);
if (ret < 0)
{
perror("recv error\n");
return -1;
}
else if (ret == 0)
{
printf("client exit\n");
break;
}
else
{
printf("buf: %s\n", buf);
}
if (strncmp(buf, "list", 4) == 0) // 获取目录
{
list(acceptfd);
}
else if (strncmp(buf, "put ", 4) == 0)
{
putf(acceptfd, buf);
}
else if (strncmp(buf, "get ", 4) == 0)
{
getf(acceptfd, buf);
}
}
// 7.关闭套接字(close)-----------------》挂电话
close(acceptfd);
}
close(socketfd);
return 0;
}
今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话点个关注支持一下吧!