C ++ - 定期发送修改后的文件

时间:2015-06-16 12:11:43

标签: c++ sockets winsock

我想用C ++定期从客户端发送文件到服务器。 比如,每10秒钟。 send.txt是我想通过socket

发送给服务器的文件

send.txt包含" 123456"前10秒。 我通过添加78910 11 12来更改文件内容,因此它变为" 123456 78910 11 12"

服务器应该收到" 123456 78910 11 12"接下来的10秒钟。但问题是我收到的文件仍然是原始文件(123456),看起来它永远不会改变。

  

这是我的客户代码:

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>




SOCKET clientsock; WSADATA winsock; sockaddr_in serverAddr , addr; int Addrlen = sizeof(serverAddr); FILE *File; unsigned long Size; char
*Buffer;

void startClient() {


    WSAStartup(MAKEWORD(2,2), &winsock);

    if(LOBYTE(winsock.wVersion) != 2 || HIBYTE(winsock.wVersion) != 2 ){

        WSACleanup();

    }


    clientsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);     addr.sin_family = AF_INET;  addr.sin_addr.s_addr = inet_addr("127.0.0.1");  addr.sin_port = htons(6091);

    connect(clientsock,(sockaddr*)&addr,sizeof(addr));

    printf("socket connected... \n");

    //preparing the file

     File = fopen("B:\\send.txt","rb");

     if(!File) {

         printf("",WSAGetLastError());   }

     printf("File open ok ! \n");


     fseek(File,0,SEEK_END);     Size = ftell(File);     fseek(File,0,SEEK_SET);


     char cisi[10];      sprintf(cisi, "%i",Size);


     send(clientsock,cisi,10,0); // file size sent

    /* Buffer = (char*) malloc (Size+1) ;    fread(Buffer,Size,1,File);      fclose(File);

     send(clientsock,Buffer,Size,0); //File binary sent      free(Buffer);   printf("sending finished ... \n"); */


}


void timer_start(std::function<void(void)> func, unsigned int interval) {
    std::thread([func, interval]() {
        while (true)
        {
            func();
            std::this_thread::sleep_for(std::chrono::milliseconds(interval));
        }
    }).detach(); }








void sending() {

            File = fopen("B:\\send.txt","rb");          fseek(File,0,SEEK_END);             Size = ftell(File);             fseek(File,0,SEEK_SET);             printf("Success...\n");

            Buffer = (char*) malloc (Size+1) ;          fread(Buffer,Size,1,File);          fclose(File);

            send(clientsock,Buffer,Size,0); //File binary sent          free(Buffer);           printf("sending finished ... \n");

}









int _tmain(int argc, _TCHAR* argv[]) {




                        startClient();

                        timer_start(sending, 10000);

                        while(true);

                        //sending();

                        //Sleep(5000);
                                        system("PAUSE");    return 0;

     }
  

,服务器代码是

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>


SOCKET servsocket, ClientAcc;
WSAData winsock;
sockaddr_in addr,incomingAddress;
int addrlen = sizeof(sockaddr_in);
int addresslen = sizeof(incomingAddress);
char *Filesize = new char[10];
int Size = 0;
char *Buffer = new char[Size];
FILE *File;

void start_p() {

    //socket initialization
    WSAStartup(MAKEWORD(2,2), &winsock);

    //socket check

    if(LOBYTE(winsock.wVersion) !=2 || HIBYTE(winsock.wVersion) != 2 ) {

        WSACleanup();
    }


    servsocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(6091);
    bind(servsocket, (sockaddr*)&addr, sizeof(addr));

    listen(servsocket, 5);

    ClientAcc = accept(servsocket, (sockaddr*)&incomingAddress, &addresslen);

    char *ClientIP = inet_ntoa(incomingAddress.sin_addr);
    int  ClientPort = ntohs(incomingAddress.sin_port);
    printf("Client Connected ... \n");
    printf("IP : %s:%d\n", ClientIP, ClientPort);

    //receive file size 

    recv(ClientAcc,Filesize,10,0);
    Size = atoi((const char*)Filesize);
    printf("File size : %d\n",Size);





}



void timer_start(std::function<void(void)> func, unsigned int interval)
{
    std::thread([func, interval]() {
        while (true)
        {
            func();
            std::this_thread::sleep_for(std::chrono::milliseconds(interval));
        }
    }).detach();
}



void receive() {

                Buffer = (char*)malloc(Size+1);
                int file_dit, total_file = 0 ;
                while(total_file < Size) {
                                                ZeroMemory(Buffer,Size);
                                                if((file_dit = recv(ClientAcc,Buffer,Size,0)) < 0 ){

                                                        goto END;

                                                } else {


                                                         total_file += file_dit;

                                                        File = fopen("B:\\fileReceived.txt", "wb");
                                                        fwrite((const char*)Buffer,1,file_dit,File);
                                                        fclose(File);
                                                        Sleep(1000);

                                                }

                                                    END:
                                                         printf("File received ... \n");
                                                         free(Buffer);
                                                         closesocket(ClientAcc);
                                                         WSACleanup();
                                                         getchar();


                                          }
}



int _tmain(int argc, _TCHAR* argv[])
{





                                    start_p();
                                    timer_start(receive, 10000);


                                    //receive();
                                    //Sleep(5000);   





                    system("PAUSE");
                    return 0;


}
  

,输出为:

     

服务器:

     

客户端连接... IP:127.0.0.1:15425文件大小:20文件   收到任何按键继续......

     

客户:

     

连接套接字......文件打开确定! ......成功......发送完毕   ......成功......发送完毕......成功......发送完毕......   成功......发送完成......成功......发送完毕......

我用这种方式

  

need to call a function at periodic time intervals in c++

定期发送文件,但结果不是我想要的。

我希望你能帮助我。谢谢。我非常感谢你的帮助。

1 个答案:

答案 0 :(得分:0)

在关闭文件之前,文件的内容实际上并未写入磁盘。我认为你在添加文本时保持文件打开,你需要在客户端再次阅读之前将其关闭。

fclose(file); // Here is when the content is written to disk.

此外,发送后你没有关闭文件。

所以,每次对文件(句柄)执行操作时,都应该在启动另一个之前将其关闭。

真正的错误必须是,你总是读到char cisi[10]并且它只有10个空格,你只发送10个字符。 send(clientsock,cisi,10,0);

更改行:

// ...
char cisi[10];
// ...
send(clientsock,cisi,10,0);

为:

// ...
char *cisi = new char[Size];
// ...
send(clientsock,cisi,Size,0);

关于服务器端代码:

recv(ClientAcc,Filesize,10,0);

使用上面的代码行,你总能得到10个字符。但在这里你不知道客户有多少个字符。

对此的基本解决方案是首先发送该号码(在文件之前),这样您就会知道为了完成接收操作你必须阅读的字符。

完整的解决方案涉及某些协议的实施。或者使用更高级的库(例如boost.Asio)。

建议:

使用fstream管理文件。毕竟,你是用c ++编写的。 ; d