问题
I want to send a file periodically from client to server in C++. say, every 10 seconds. send.txt is the file that i want to send to server through socket
send.txt contains "123456" for the first 10 seconds. i change the file content by adding 78910 11 12 so it becomes "123456 78910 11 12"
the server should receive "123456 78910 11 12" for the next 10 seconds. but the problem is the file that i received is still the original one (123456) and look like it never changes.
here is my client code :
#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;
}
and the server code is
#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;
}
and the output is :
server :
client connected... IP : 127.0.0.1 : 15425 File size : 20 File received press any key to continue ...
client :
Socket connected... File open ok ! ... success ... sending finished ... success ... sending finished ... success ... sending finished ... success ... sending finished ... success ... sending finished ...
i used this way
need to call a function at periodic time intervals in c++
to send the file periodically but the result is not what i want.
i hope you can help me . thank you. i really appreciate your help.
回答1:
The content of the file is not actually written to disk until you close the file. I'm think you are keeping the file open while adding text, you need to close it before the client read again from it.
fclose(file); // Here is when the content is written to disk.
Besides, you aren't closing the file after sending it.
So, every time you perform an operation over the file (handle) you should close it before start another.
And the true error must be that you allways are reading to char cisi[10]
and it has only 10 spaces equally you're only sending 10 characters. send(clientsock,cisi,10,0);
Change the lines:
// ...
char cisi[10];
// ...
send(clientsock,cisi,10,0);
to:
// ...
char *cisi = new char[Size];
// ...
send(clientsock,cisi,Size,0);
About server side code:
recv(ClientAcc,Filesize,10,0);
With the above line of code you always will get 10 chars. But here you don't know how many chars comes from the client.
A basic solution for this is to send that number first (before the file), that way you'll know how chars you have to read for complete the receiving operation.
A complete solution involves the implementation of some protocol. Or the use of a more advanced library (E.g boost.Asio).
Recommendation:
Use fstream to manage files. After all, you're coding in c++. ;D
来源:https://stackoverflow.com/questions/30867235/c-sending-a-modified-file-periodically