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

客服端功能如下:
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;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在VS2010中,利用TCP套接字实现客户服务器端双向聊天和文件传输首先需要建立一个服务器端和一个客户端。服务器端监听指定端口,等待客户端连接。客户端通过指定服务器地址和端口连接到服务器端。 在服务器端,首先创建一个监听socket,使用`socket()`函数创建套接字。然后通过`bind()`函数将套接字与指定的IP地址和端口绑定。接着通过`listen()`函数将套接字设置为监听状态,等待客户端连接请求。 在客户端,通过`socket()`函数创建一个套接字使用`connect()`函数将该套接字服务器端的IP地址和端口连接起来。 连接建立后,服务器端通过`accept()`函数接受客户端的连接请求,并获取到新的套接字,用于与该客户端进行通信。客户端则开始与服务器端进行通信。 双向聊天:服务器端和客户端可以通过套接字的`send()`和`recv()`函数进行双向通信。服务器通过`recv()`函数接收客户端发送的消息,并通过`send()`函数将回复消息发送给客户端。客户端则相反,通过`recv()`函数接收服务器端发送的消息,并通过`send()`函数将回复消息发送给服务器端。这样双方便可以实现双向聊天。 文件传输:服务器端和客户端可以通过套接字的`send()`和`recv()`函数进行文件传输。服务器端将要传输的文件打开,并通过`send()`函数将文件内容发送给客户端。客户端通过`recv()`函数接收服务器端发送的文件内容,并在本地保存为文件。同样地,客户端也可以将文件发送给服务器端,方法与服务器端相同。 在双向聊天和文件传输完成后,可以通过`close()`函数关闭套接字连接,释放资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值