简单的C++ 实现ftp服务器

  • Post author:
  • Post category:其他


Linux 服务端, Windows 客户端

客户端负责输入要下载的文件名字, 服务器负责传送,

但这个代码非常简单,后期可以加好多功能,比如

  • 大文件传输

    显示有多少文件名

    上传文件



Server

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>

#pragma pack(1)
class File {
public:
    int     m_fsize;
    char    m_fname[30];

    char    package[1024];

    void getfilename(int fd){
        char buf[2000];    
        int len = read(fd, buf, sizeof(buf));

        // 获取文件信息
        File *tmp = (File*)buf;
        strcpy(m_fname, tmp->m_fname);

        struct stat fileinfo;
        stat(m_fname, &fileinfo);
        m_fsize = fileinfo.st_size;

    }

    void sendfileinfo(int fd){
        FILE* wfd = fopen(m_fname, "rb");

        int num = fread(package, sizeof(char), m_fsize, wfd);
        package[m_fsize] = '\0';

        char *psendfile = (char*)(this);

        num = write(fd, psendfile, sizeof(File));
        
        fclose(wfd);
    }
};
#pragma pack()

int main()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1){
        cout << "socket error" << endl;
        return 0;
    }
    //允许地址的立即重用    
    char on = 1;
	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    struct sockaddr_in saddr, caddr;
    memset(&saddr, 0, sizeof(sockaddr_in));
    saddr.sin_addr.s_addr = inet_addr("192.168.17.128");
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(9999);

    if(-1 == bind(fd, (struct sockaddr*)&saddr, sizeof(struct sockaddr))){
        cout << "bind error" << endl;
        return 0;
    }

    if(-1 == listen(fd, 1024)){
        cout << "listen error" << endl;
        return 0;
    }

    int len = sizeof(caddr);
    int cfd = accept(fd, (struct sockaddr*)&caddr, (socklen_t*)&len);

    File* pfile = new File();
    while(1){
        pfile->getfilename(cfd);
        pfile->sendfileinfo(cfd);
    }

    delete pfile;
    close(cfd);
    close(fd);
    return 0;
}



Client

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#include    <winsock2.h>
#include    <Ws2tcpip.h>
#include    <Windows.h>
#pragma comment(lib,"WS2_32")

#pragma pack(1)
class File {
public:
    int     m_fsize;
    char    m_fname[30];
    char    package[1024];
};
#pragma pack()

int main() 
{

    
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        exit(1);
    }
    SOCKADDR_IN ServerAddr;

    SOCKET S = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(9999);
    inet_pton(AF_INET, "192.168.17.128", (void*)&ServerAddr.sin_addr.S_un.S_addr);
    connect(S, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr));


    while (1) {


        File file;
        cin >> file.m_fname;
        if (strcmp(file.m_fname, "quit") == 0) break;
        int len = send(S, (char*)&file, sizeof(file), 0);
        char buf[2000];

        int num = recv(S, buf, sizeof(buf), 0);


        File* precv = (File*)buf;

        FILE* p = fopen(file.m_fname, "wb");
        num = fwrite(precv->package, sizeof(char), precv->m_fsize, p);
        printf("%s %d", precv->package, num);

    }

    closesocket(S);
    WSACleanup();
	return 0;
}

在这里插入图片描述



版权声明:本文为weixin_52068490原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。