编写tcp文件服务器和客户端。客户端可以上传和下载文件
客户端功能如下:
1.支持以下命令:
help:显示客户端所有命令和说明
list:显示服务器端可下载文件列表
get<file>:下载文件
put<file>:上传文件
quit: 退出客户端
服务器端功能(单进程):
解析客户端命令并提供相应服务
服务器端:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<dirent.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define N 128
typedef struct sockaddr SA;
void ProcessList(int connfd)
{
char buf[N];
DIR *mydir;
struct dirent *myitem;
mydir=opendir(".");
while((myitem=readdir(mydir))!=NULL)
{
if((strcmp(myitem->d_name,".")==0)||(strcmp(myitem->d_name,"..")==0)) continue;
strcpy(buf,myitem->d_name);
send(connfd,buf,N,0);
}
closedir(mydir);
return;
}
void ProcessGet(int connfd,char buf[])
{
int fd,nbyte;
if((fd=open(buf+1,O_RDONLY))<0)
{
printf("fail to open%s\n",buf+1);
buf[0]='N';
send(connfd,buf,N,0);
return;
}
buf[0]='Y';
send(connfd,buf,N,0);
while((nbyte=read(fd,buf,N))>0)
{
send(connfd,buf,nbyte,0);
}
close(fd);
return;
}
void ProcessPut(int connfd,char buf[])
{
int fd,nbyte;
if((fd=open(buf+1,O_WRONLY|O_CREAT|O_TRUNC,0666))<0)
{
printf("fail to create %s on server\n",buf+1);
return;
}
while((nbyte=recv(connfd,buf,N,0))>0)
{
write(fd,buf,nbyte);
}
close(fd);
return;
}
int main(int argc,char **argv)
{
int listenfd,connfd;
char buf[N];
struct sockaddr_in server_addr;
if((listenfd=socket(PF_INET,SOCK_STREAM,0))<0)
{
printf("socket error\n");
exit(-1);
}
printf("socket is %d\n",listenfd);
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(8888);
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(listenfd,(SA *)&server_addr,sizeof(server_addr))<0)
{
printf("fail to binf\n");
exit(-1);
}
listen(listenfd,5);
while(1)
{
if((connfd=accept(listenfd,NULL,NULL))<0)
{
printf("fail to accept\n");
break;
}
recv(connfd,buf,N,0);
switch(buf[0])
{
case 'L':ProcessList(connfd);break;
case 'G':ProcessGet(connfd,buf);break;
case 'P':ProcessPut(connfd,buf);break;
}
close(connfd);
}
return 0;
}
客户端:
/* client2 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#define N 128
typedef struct sockaddr SA;
void PrintHelp()
{
printf("help : display help info\n");
printf("list : get file list of server\n");
printf("get : get <file>\n");
printf("put : put <file>\n");
printf("quit : quit the client\n");
return;
}
void ProcessList(struct sockaddr_in server_addr)
{
int sockfd, nbyte;
char buf[N];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to list\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_1;
}
strcpy(buf, "L");
send(sockfd, buf, N, 0);
while ((nbyte = recv(sockfd, buf, N, 0)) != 0)
{
printf("%s\n", buf);
}
ERROR_1:
close(sockfd);
return;
}
void ProcessGet(struct sockaddr_in server_addr, char command[])
{
int sockfd, nbyte, fd;
char buf[N];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to get\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_2;
}
sprintf(buf, "G%s", command+4);
send(sockfd, buf, N, 0);
recv(sockfd, buf, N, 0);
if (buf[0] == 'N') // no such file
{
printf("No such file on server\n");
goto ERROR_2;
}
if ((fd = open(command+4, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
{
printf("fail to create local file %s\n", command+4);
goto ERROR_2;
}
while ((nbyte = recv(sockfd, buf, N, 0)) > 0)
{
write(fd, buf, nbyte);
}
close(fd);
ERROR_2:
close(sockfd);
return;
}
void ProcessPut(struct sockaddr_in server_addr, char command[])
{
int sockfd, fd, nbyte;
char buf[N];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to get\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_3;
}
if ((fd = open(command+4, O_RDONLY)) < 0)
{
printf("fail to open %s\n", command+4);
goto ERROR_3;
}
sprintf(buf, "P%s", command+4);
send(sockfd, buf, N, 0);
while ((nbyte = read(fd, buf, N)) > 0)
{
send(sockfd, buf, nbyte, 0);
}
close(fd);
ERROR_3:
close(sockfd);
return;
}
int main(int argc, char *argv[])
{
int sockfd, fd, nbyte;
char command[32];
struct sockaddr_in server_addr;
if (argc < 3)
{
printf("Usage : %s <server_ip> : <port>\n", argv[0]);
exit(-1);
}
// XXX:step 1 int socket(int domain, int type, int protocol);
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr, "fail to socket : %s\n", strerror(errno));
exit(-1);
}
#ifdef _DEBUG_
printf("socket is %d\n", sockfd);
#endif
// XXX:step 2 int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
//server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
while ( 1 )
{
printf("<client> ");
fgets(command, 32, stdin);
command[strlen(command)-1] = '\0'; // overwrite the '\n'
if (strcmp(command, "help") == 0)
{
PrintHelp();
}
else if (strcmp(command, "list") == 0)
{
ProcessList(server_addr);
}
else if (strncmp(command, "get ", 4) == 0)
{
ProcessGet(server_addr, command);
}
else if (strncmp(command, "put ", 4) == 0)
{
ProcessPut(server_addr, command);
}
else if (strcmp(command, "quit") == 0)
{
printf("Bye\n");
break;
}
else
{
printf("wrong command, 'help' for command list\n");
}
}
return 0;
}