• ftp并发套接字编程


    基于ftp的多线程Socket编程,服务器端和客户端可以互传文件。

    编译环境:VS2019,VC++

    先在D盘添加file_server和file_client文件夹,在里面可以新建一些文件,方便客户端上传与下载。

    有注释,贴上源码,供大家学习参考。

    服务器端 Server.cpp

    #include <windows.h>
    #include <stdio.h>
    #include<iostream>
    #include <string.h>
    #pragma comment (lib,"ws2_32")
    using namespace std;
    #define BUF_SIZE 1024
    
    void RecvFile(char name[], SOCKET s) {
    
        char FileName[MAXBYTE] = "";
        sprintf(FileName, "D:\file_server\%s", name);
    
        char info[BUF_SIZE];
        recv(s, info, BUF_SIZE, 0);
        cout << info << endl;
    
        if (!strcmp(info, "传输文件失败, 文件不存在!
    ")) {
    
        }
        else {
            DWORD dwWrite;
            HANDLE hFile = CreateFile(FileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
            char szBufferfile[BUF_SIZE] = { NULL };
            char ok[BUF_SIZE] = { NULL };
    
            while (true) {
    
                int read = recv(s, szBufferfile, BUF_SIZE, 0);
                if (!strcmp(ok, szBufferfile)) {
                    printf("接收文件成功!!!
    "); break;
                }
                bool bRet = WriteFile(hFile, szBufferfile, read, &dwWrite, NULL);
            }
    
            CloseHandle(hFile);
        }
        
    }
    
    
    void Sender(char name[], SOCKET clientSock) {
    
        char FileName[MAXBYTE] = "";
        sprintf(FileName, "D:\file_server\%s", name);
    
        char ok[BUF_SIZE] = { NULL };
        char SendBuf[BUF_SIZE] = { NULL };
        DWORD dwRead;
        HANDLE hFile = CreateFile(FileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        if (hFile == INVALID_HANDLE_VALUE) {
            send(clientSock, "传输文件失败, 文件不存在!
    ", BUF_SIZE, 0);
        }
        else {
            send(clientSock, "开始接收文件
    ", BUF_SIZE, 0);
            while (TRUE) {
                bool bRet = ReadFile(hFile, SendBuf, BUF_SIZE, &dwRead, NULL);
                if (bRet == FALSE) {
                    //MessageBox(NULL, "Read Buf ERROR!", "Error", MB_OK);
                    CloseHandle(hFile);
                    break;
                }
                else if (dwRead == 0)
                {
                    //MessageBox(NULL, "Send file OK!", "OK", MB_OK);
                    CloseHandle(hFile);
                    printf("发送文件成功!!!
    ");
                    send(clientSock, ok, BUF_SIZE, 0);
                    break;
                }
                else
                {
                    send(clientSock, SendBuf, BUF_SIZE, 0);
                }
            }
        }
    }
    
    
    DWORD WINAPI ClientThread(LPVOID IpParam) {
        SOCKET clientSock = (SOCKET)IpParam;
        printf("与客户端取得连接,套接字编号为%u
    ", clientSock);
    
        char RecvBuf[MAXBYTE];
        char FileName[MAXBYTE] = { NULL };
        int read = 0;
        char getcheck[6] = { "down" };
        char upcheck[6] = { "up" };
    
        while (true) {
            memset(RecvBuf, 0, MAXBYTE);//与客户端进行文字通信
            read = recv(clientSock, RecvBuf, MAXBYTE, 0);
    
            if (read == -1) break;
    
            printf(RecvBuf);
            printf("
    ");
    
            if (!strcmp(RecvBuf, getcheck)) {        // get 下载文件
    
                memset(FileName, 0, MAXBYTE);
    
                read = recv(clientSock, FileName, MAXBYTE, 0);
                if (read == -1) break;
                printf("%s
    ", FileName);
                Sender(FileName, clientSock);
    
            }
            else if (!strcmp(RecvBuf, upcheck)) {
    
                memset(FileName, 0, MAXBYTE);
                recv(clientSock, FileName, MAXBYTE, 0);
                RecvFile(FileName, clientSock);
    
            }
            else {
                send(clientSock, "无效的命令,请重新输入..
    ", MAXBYTE, NULL);
            }
        }
    
        closesocket(clientSock);
        return 0;
    }
    
    int main(int argc, char* argv[]) {
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2, 2), &wsaData);
    
        SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);                                //套接字s用于监听
    
        sockaddr_in sockaddr;
        sockaddr.sin_family = PF_INET;
        sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
        sockaddr.sin_port = htons(827);
        bind(s, (SOCKADDR*)&sockaddr, sizeof(sockaddr));                                     //绑定套接字 ip,端口号
    
        SOCKADDR clientAddr = { 0 };
        int nSize = sizeof(SOCKADDR);
        SOCKET clientSock;
    
        listen(s, 1);
        //循环接受客户端连接请求,并生成线程去处理:
        printf("I'm server
    ");
        while(1) {
            //等待接受客户端控制连接请求
            clientSock = accept(s, (SOCKADDR*)&clientAddr, &nSize);
    
            //创建一个线程来处理相应客户端的请求:
            DWORD dwThreadId, dwThrdParam = 1;
            HANDLE hThread;
    
            hThread = CreateThread(
                NULL,               //无需安全性的继承
                0,                    //默认线程栈大小
                ClientThread,            //线程入口函数
                (LPVOID)clientSock,            //线程入口函数的参数
                0,                    //立即启动线程
                &dwThreadId);        //返回线程的id值
    
            //检查返回值是否创建线程成功
            if (hThread == NULL) {
                printf("创建线程失败。
    ");
                closesocket(s);
            }
    
            CloseHandle(hThread);
        }
        
        closesocket(clientSock);
        closesocket(s);
    
        WSACleanup();
    
        return 0;
    }

    客户端 Client.cpp

    #include<iostream>
    #include<winsock2.h>
    #pragma comment (lib,"ws2_32")
    using namespace std;
    
    #define BUF_SIZE 1024
    void RecvFile(char name[], SOCKET s) {
    
        char FileName[MAXBYTE] = "";
        sprintf(FileName, "D:\file_client\%s", name);
    
        char info[BUF_SIZE];
        recv(s, info, BUF_SIZE, 0);
        cout << info << endl;
    
        if (!strcmp(info, "传输文件失败, 文件不存在!
    ")) {
    
        }
        else {
            DWORD dwWrite;
            HANDLE hFile = CreateFile(FileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
            char szBufferfile[BUF_SIZE] = { NULL };
            char ok[BUF_SIZE] = { NULL };
    
            while (true) {
    
                int read = recv(s, szBufferfile, BUF_SIZE, 0);
                if (!strcmp(ok, szBufferfile)) {
                    printf("已接收到文件!!!
    "); break;
                }
                bool bRet = WriteFile(hFile, szBufferfile, read, &dwWrite, NULL);
            }
    
            CloseHandle(hFile);
            printf("写入文件成功!!!
    ");
        }
    }
    
    void Sender(char name[], SOCKET clientSock) {
    
        char FileName[MAXBYTE] = "";
        sprintf(FileName, "D:\file_client\%s", name);
    
        char ok[BUF_SIZE] = { NULL };
        char SendBuf[BUF_SIZE] = { NULL };
        DWORD dwRead;
        HANDLE hFile = CreateFile(FileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        if (hFile == INVALID_HANDLE_VALUE) {
            cout << "传输文件失败, 文件不存在!" << endl;
            send(clientSock, "传输文件失败, 文件不存在!
    ", BUF_SIZE, 0);
        }
        else {
            send(clientSock, "开始接收文件...
    ", BUF_SIZE, 0);
            while (TRUE) {
                bool bRet = ReadFile(hFile, SendBuf, BUF_SIZE, &dwRead, NULL);
                if (bRet == FALSE) {
                    //MessageBox(NULL, "Read Buf ERROR!", "Error", MB_OK);
                    CloseHandle(hFile);
                    break;
                }
                else if (dwRead == 0)
                {
                    //MessageBox(NULL, "Send file OK!", "OK", MB_OK);
                    CloseHandle(hFile);
                    printf("发送文件成功!!!
    ");
                    send(clientSock, ok, BUF_SIZE, 0);
                    break;
                }
                else
                {
                    send(clientSock, SendBuf, BUF_SIZE, 0);
                }
            }
        }
    }
    
    int main(int argc, char* argv[])
    {
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2, 2), &wsaData);
    
        SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);                 //创建套接字
    
        sockaddr_in sockAddr;
        sockAddr.sin_family = PF_INET;
        sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
        sockAddr.sin_port = htons(827);
    
        char SendBuf[MAXBYTE];
        char szBuffer[MAXBYTE] = { NULL };
        char FileName[MAXBYTE] = { NULL };
        char getcheck[6] = { "down" };
        char upcheck[6] = { "up" };
        char bye[6] = { "exit" };
    
        printf("I'm Client
    1)down:从服务端下载文件
    2)up:上传文件到服务器
    3)exit:退出
    ");
        //cout << "Server:" << endl;
        connect(s, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));                     //给服务器端发送TCP链接请求
    
        while (TRUE) {
            cout << "Client:";
            memset(SendBuf, 0, MAXBYTE);
            cin >> SendBuf;
    
            if (!strcmp(SendBuf, getcheck)) {
                send(s, SendBuf, MAXBYTE, NULL);
                cout << "filename:";
                memset(FileName, 0, MAXBYTE);
        
                cin >> FileName;
                send(s, FileName, MAXBYTE, NULL);
                RecvFile(FileName, s);
                continue;
            }
    
            else if (!strcmp(SendBuf, upcheck)) {
                send(s, SendBuf, MAXBYTE, NULL);
                cout << "filename:";
                memset(FileName, 0, MAXBYTE);
    
                cin >> FileName;
                send(s, FileName, MAXBYTE, NULL);
                Sender(FileName, s);
                continue;
            }
            else if (!strcmp(SendBuf, bye)) {
    
                cout << "已退出。
    " << endl;
                break;
    
            }
            send(s, SendBuf, MAXBYTE, NULL);
            memset(szBuffer, 0, MAXBYTE);
            memset(SendBuf, 0, MAXBYTE);
            recv(s, szBuffer, MAXBYTE, NULL);
            cout << szBuffer;
        }
        closesocket(s);
        WSACleanup();
        return 0;
    }
  • 相关阅读:
    从编程到入侵
    编程实现盗2005 Beta2版QQ
    Justin Frankel:Winamp的反斗奇星
    用安静的热情征服联合国
    我和试用期员工之间的故事
    Sogou输入法之父给我们的启示
    《ATL开发指南》的一个值得商榷的地方
    厦门PX项目迁址:意义有限的进步
    探析项目主导型的IT业的人员需求变化及其应对办法
    今天,影响了一位试用期员工的去留
  • 原文地址:https://www.cnblogs.com/wqvincent/p/14691911.html
Copyright © 2020-2023  润新知