您的位置:首页 > 理论基础 > 计算机网络

使用TCP套接字实现文件服务器

2012-11-12 13:35 465 查看
客服端功能如下:
1.支持一下命令
help :显示客服端所有的命令和说明
list :显示服务器端可下载文件列表
get <file> : 下载文件
put <file> : 上传文件
quit :退出客服端

服务器端单进程解析客服端命令并提供服务

服务器端代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#define SA struct sockaddr
#define BUFF 1024
char buf[BUFF];
void do_list(int fd)
{
DIR *dir;
struct dirent *pst_dir;
char name[20];
printf("client requst list\n");
dir = opendir(".");
while ((pst_dir = readdir(dir)) != NULL)
{
if (pst_dir->d_name[0] != '.')
{
strcpy(name, pst_dir->d_name);
strcat(name, "\n");
send(fd, name, strlen(name), 0);
}
}
closedir(dir);
printf("sended list for client\n");
return;
}
void do_get(int connfd)
{
int nbyte, fd;
char name[20];
recv(connfd, name, 20, 0);
printf("client need download file name %s\n", name);
if ((fd = open(name, O_RDONLY)) == -1)
{
perror("open file fail");
strcpy(buf, "N");
send(connfd, buf, 1, 0);
return;
}
strcpy(buf, "Y");
send(connfd, buf, 1, 0);
while ((nbyte = read(fd, buf, BUFF)) > 0)
{
send(connfd, buf, nbyte, 0);
}
close(fd);
printf("downloaded\n");
return;
}
void do_put(int connfd)
{
int nbyte, fd;
char name[20];
recv(connfd, name, 20, 0);
printf("client need upload file name %s\n", name);
recv(connfd, buf, 1, 0);
if (buf[0] == 'N')
{
printf("client not have the file\n");
return;
}
if ((fd = open(name, O_WRONLY|O_CREAT|O_EXCL, 0666)) == -1)
{
perror("open file fail");
return;
}
while ((nbyte = recv(connfd, buf, BUFF, 0)) > 0)
{
write(fd, buf, nbyte);
}
close(fd);
printf("uploaded\n");
return;
}
int main(int argc, char *argv[])
{
int listenfd, connfd, addr_len, read_byte;
struct sockaddr_in ser_addr, cli_addr;
if (argc < 3)
{
printf("input format is:%s <ip> <port>\n", argv[0]);
exit(1);
}
//int socket(int domain, int type, int protocol);
if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket fail");
exit(1);
}
// int bind(int sockfd, const struct sockaddr *addr,
// socklen_t addrlen);
ser_addr.sin_family = PF_INET;
ser_addr.sin_port = htons(atoi(argv[2]));
ser_addr.sin_addr.s_addr = inet_addr(argv[1]);
bzero(&ser_addr.sin_zero, 8);
if (bind(listenfd, (SA *)&ser_addr, sizeof(ser_addr)) == -1)
{
perror("bind fail");
exit(1);
}
// int listen(int sockfd, int backlog);
if (listen(listenfd, 5) == -1)
{
perror("listen fail");
exit(1);
}
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
while (1)
{
connfd = 0;
printf("server->\n");
addr_len = sizeof(cli_addr);
if ((connfd = accept(listenfd, (SA *)&cli_addr, &addr_len)) == -1)
{
perror("accept fail");
exit(1);
}
//printf("the client is %s:%d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
if ((read_byte = recv(connfd, buf, 10, 0)) == -1)
{
perror("read fail\n");
exit(1);
}
switch (buf[0])
{
case '1':
do_list(connfd);
break;
case '2':
do_get(connfd);
break;
case '3':
do_put(connfd);
break;
}
close(connfd);
memset(buf, 0, BUFF);
}
return 0;
}

客服端代码如下:

#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SA struct sockaddr
#define BUFF 50
char buf[BUFF];
void do_help()
{
printf("please input the follow command\n");
printf("1 help -----> dispaly the command\n");
printf("2 list -----> list the server file\n");
printf("3 get <file> -----> download the <file> from server\n");
printf("4 put <file> -----> send the file to server\n");
printf("5 quit -----> quit it\n");
return;
}
void do_list(int fd)
{
int nbyte;
strcpy(buf, "1");
send(fd, buf, 1, 0);
while ((nbyte = recv(fd, buf, BUFF, 0)) > 0)
{
write(1, buf, nbyte);
}
}
void do_get(int connfd, char *name)
{
int nbyte, fd;
strcpy(buf, "2");
send(connfd, buf, 1, 0);
send(connfd, name, strlen(name), 0);
recv(connfd, buf, 1, 0);
if (buf[0] == 'N')
{
printf("server not have the file\n");
return;
}
if ((fd = open(name, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1)
{
perror("open file fail");
return;
}
while ((nbyte = recv(connfd, buf, BUFF, 0)) > 0)
{
write(fd, buf, nbyte);
}
close(fd);
return;
}
void do_put(int connfd, char *name)
{
int nbyte, fd;
strcpy(buf, "3");
send(connfd, buf, 1, 0);
send(connfd, name, strlen(name), 0);
if ((fd = open(name, O_RDONLY)) == -1)
{
perror("open file fail");
strcpy(buf, "N");
send(connfd, buf, 1, 0);
return;
}
strcpy(buf, "Y");
send(connfd, buf, 1, 0);
while ((nbyte = read(fd, buf, BUFF)) > 0)
{
send(connfd, buf, nbyte, 0);
}
close(fd);
return;
}
int main(int argc, char *argv[])
{
int connfd;
char s[20], file_name[20], command[10];
struct sockaddr_in ser_addr;
if (argc < 3)
{
printf("input format is:%s <ip> <port>\n", argv[0]);
exit(1);
}

//int connect(int sockfd, const struct sockaddr *serv_addr,
// socklen_t addrlen);
ser_addr.sin_family = PF_INET;
ser_addr.sin_port = htons(atoi(argv[2]));
ser_addr.sin_addr.s_addr = inet_addr(argv[1]);
bzero(&ser_addr.sin_zero, 8);
while (1)
{
if ((connfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket fail\n");
exit(1);
}
memset(file_name, 0, strlen(file_name));
printf("client->");
fgets(s, 20, stdin);
s[strlen(s)-1] = '\0';
if (!strcmp(s, "help"))
{
do_help();
continue;
}
if (!strcmp(s, "quit"))
{
break;
}
if (connect(connfd, (SA *)&ser_addr, sizeof(ser_addr)) == -1)
{
perror("connect fail");
exit(1);
}
if (!strcmp(s, "list"))
{
do_list(connfd);
}
// get file name
sscanf(s, "%s %s", command, file_name);
if (!strcmp(command, "get"))
{
do_get(connfd, file_name);
}
if (!strcmp(command, "put"))
{
do_put(connfd, file_name);
}
close(connfd);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: