试图通过套接字接收文件

时间:2010-10-10 21:40:13

标签: c++ sockets

从tcp套接字发送和接收文件。发送文件有效,但尝试保存文件不起作用。

#include <cassert>
#include <arpa/inet.h>
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <fstream>
#include <time.h>
#include <strings.h>
#include <sstream>
#include <vector> 
#include <netdb.h>
#include <netinet/in.h>
#include <sys/sendfile.h>
#include <fcntl.h>

using namespace std;
using std::endl;

int newscount = 0;
int doccount = 0;
int photocount = 0;
int johns = 0;
vector<string> newsvector;
vector<string> photosvector;
vector<string> docsvector;

void serverlogs(const char*msg) /* writing to log file  */
{

time_t rawtime;
struct tm * timeinfo;
time (&rawtime);
timeinfo = localtime(&rawtime);


ofstream file;
file.open("serverlog.txt",ios::app);
if (file.is_open())
{file<<msg;
file<<" @ ";
file<<asctime(timeinfo);
file<<"\n";
file.close();
return;
}
else
cout<<"Error Creating log file";
return;
}

void clientlogs(const char*msg) /* writing to log file  */
{
time_t rawtime;
struct tm * timeinfo;
time (&rawtime);
timeinfo = localtime(&rawtime);
ofstream file;
file.open("clientlog.txt",ios::app);
if (file.is_open())
{file<<msg;
file<<" @ ";
file<<asctime(timeinfo);
file<<"\n";
file.close();
return;
}
else
cout<<"Error Creating log file";
return;
}
void error(const char*msg)    /* If there is an error exit the program with err# 1  */
{
perror(msg);
exit(1);
}

void publishdocsvector(const char*msg)
{
    docsvector.push_back(msg);  
    ofstream file;
    file.open("docfiles.txt",ios::app);
    if (file.is_open())
    {
    for(int j = 0; j < docsvector.size() ;j++)
    {file<<docsvector[j];}
    file.close();
    }
else
cout<<"Error creating news archive";
return;
}
void publishphotosvector(const char*msg)
{
    photosvector.push_back(msg);    
    ofstream file;
    file.open("photofiles.txt",ios::app);
    if (file.is_open())
    {
    for(int j = 0; j < photosvector.size() ;j++)
    {file<<photosvector[j];}
    file.close();
    }
else
cout<<"Error creating news archive";
return;
}
void publishnewsvector(const char*msg)
{
    newsvector.push_back(msg);  
    ofstream file;
    file.open("newsfiles.txt",ios::app);
    if (file.is_open())
    {
    for(int j = 0; j < newsvector.size() ;j++)
    {file<<newsvector[j];}
    file.close();
    }
else
cout<<"Error creating news archive";
return;
}   

void sendfile(const char*msg)
{
// to be implemented later//    
}


int main (int argc, char*argv[]) /*Main Program accepting a port number and something      else for arguments */
{

int sockfd, newsockfd, portno, clilen, n,test;
string publish="publish";
string search= "search";
string get="get";
string newsstring = "news";
string docstring = "doc";
string photostring = "photo";
string wrap = "exit";
char buffer[256];
char seats [50];
serverlogs("Server Running");
struct sockaddr_in serv_addr, cli_addr; /* Defines the server address and client address and types of structures with the same format as socket address */
if (argc < 2)
{
    fprintf(stderr,"Please provide a port number next time plz, goodbye!");
    exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0); /* If Sock_Dgram then then it will open a udp socket */
if (sockfd < 0)
error("Error opening socket");
bzero((char *)&serv_addr, sizeof(serv_addr)); /* sets the server address to zero usings its reference */
portno = atoi(argv[1]); /*2nd argument vector is the port number and converted into an integer, the first [0] is the running program */
serv_addr.sin_family = AF_INET; /* The structure sockaddr_in has four fields, this is first one and should always be this */
serv_addr.sin_port = htons(portno); /* convert port number into network byte order */
serv_addr.sin_addr.s_addr = INADDR_ANY; /*3rd Field uses Ip address of host machine */
if (bind(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr))<0) /*bind socket to sockfd and address of server ,and needs size of address need struct of sockaddr, see bind man for details*/
    error("Couldn't bind socket to address");
listen(sockfd,5);
clilen = sizeof(cli_addr);
serverlogs("going into server loop");
int pid = fork();
if (pid < 0)
    serverlogs("error on initial separtion of server and client");
if (pid==0)
{
// server loop later on this will be the child process and client will be main
while (1) 
{ /* Server loop loop*/
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, (socklen_t*)&clilen);
if (newsockfd < 0)
    /* error("Corrupt log"); */
    serverlogs("Connection not accepted");
else (newsockfd > 0);
int ppID = fork();
if (ppID < 0)
    serverlogs("A new server process failed to be created");
if (ppID == 0)
{

    int uid;
    uid = johns;

printf("A new client connected with identity: %d\n", getpid());
close(sockfd);
serverlogs("A john Connected to the server");
printf("my unique id: %d\n", uid);
serverlogs(seats);
bzero(buffer,256);
//n = write(newsockfd,"Each client is a 'john' \n",26);
/* This loop read from socket and writes to other persons sockets */
    while(1)
    {
    bzero(buffer,256);
    n = read(newsockfd,buffer,256);
    if (n < 0) 
        printf ("error reading from socket here is the message: %s",buffer);
        if (publish[0] == buffer[0])
            {
                n = write(newsockfd,"What category are you publishing in?(news,photos,documents) \n",62);
                bzero(buffer,256);
                n = read(newsockfd,buffer,256);
                if(buffer[0]==newsstring[0])
                {
                    n = write(newsockfd,"Type the name of the file to publish and wait 10 seconds \n",59);
                    bzero(buffer,256);
                    n = read(newsockfd,buffer,256);
                    publishnewsvector(buffer);
                    serverlogs(seats);
                    serverlogs("client is trying to publish a news file:");
                    serverlogs(buffer);
                    /*start recieving a file*/
                    std::ofstream file;
                    file.open(buffer, std::ios::out | std::ios::binary);
                    assert(file.is_open());
                    while (1) {
                    std::cout << "..";
                    bzero(buffer,256);
                    n = read(newsockfd, buffer, sizeof(buffer));
                    assert(n != -1);
                    if (n == 0)
                    break;
                    file.write(buffer, n);
                    i++;
                                }
                    file.close();
                    serverlogs("File Transfered successfully");

                }
                if(buffer[0]==docstring[0])
                {
                    n = write(newsockfd,"Type the name of the file to publish \n",39);
                    bzero(buffer,256);
                    n = read(newsockfd,buffer,256);
                    publishdocsvector(buffer);
                    serverlogs(seats);
                    serverlogs("client is tyring to publish a document:" );
                    serverlogs(buffer);
                    /*start recieving a file*/

                    std::ofstream file;
                    file.open(buffer, std::ios::out | std::ios::binary);
                    assert(file.is_open());
                    while (1) {
                    std::cout << ".";
                    bzero(buffer,256);
                    n = read(newsockfd, buffer, sizeof(buffer));
                    assert(n != -1);
                    if (n == 0)
                    break;
                    file.write(buffer, n);
                                }
                    file.close();
                    serverlogs("File Transfered successfully");

                }
                if(buffer[0]==photostring[0])
                {
                    n = write(newsockfd,"Type the name of the file to publish \n",39);
                    bzero(buffer,256);
                    n = read(newsockfd,buffer,256);
                    publishphotosvector(buffer);
                    serverlogs(seats);
                    serverlogs("client is trying to publish photo file:" );
                    serverlogs(buffer);
                    /*start recieving a file*/
                    std::ofstream file;
                    file.open(buffer, std::ios::out | std::ios::binary);
                    assert(file.is_open());
                    while (1) {
                    std::cout << ".";
                    bzero(buffer,256);
                    n = read(newsockfd, buffer, sizeof(buffer));
                    assert(n != -1);
                    if (n == 0)
                    break;
                    file.write(buffer, n);
                                }
                    file.close();
                    serverlogs("File Transfered successfully");
                }

            }
        if (get[0] ==buffer[0])
            {
                n = write(newsockfd,"\n What file do you want to get? \n",35);
                bzero(buffer,256);
                n = read(newsockfd,buffer,256);
                serverlogs(seats);
                serverlogs("client wants file:");
                serverlogs(buffer);
                //** start sending the file**//
                    FILE* searchfile = 0;
                    long Size = 0; 
                    searchfile = fopen(buffer,"r");
                    fseek(searchfile, 0, SEEK_END); 
                    Size = ftell(searchfile); 
                    char *bufferfile = (char*)malloc(Size); 
                    memset(bufferfile, 0, Size); 
                    fseek(searchfile, 0, SEEK_SET); 
                    fread(bufferfile, Size, 1, searchfile); 
                    n = write(newsockfd,bufferfile,256);
                    fclose(searchfile); 
                serverlogs("Sent the file to the client");
                serverlogs(seats);

            }


        if (search[0] == buffer[0])
            {
            bzero(buffer,256);
            n = write(newsockfd,"What category are you searching? \n",35);
            bzero(buffer,256);
            n = read(newsockfd,buffer,256);
            serverlogs(seats);
            serverlogs("client searching for");
            serverlogs(buffer);
            if(buffer[0]==newsstring[0])
                {
                    FILE* searchfile = 0;
                    long Size = 0; 
                    searchfile = fopen("newsfiles.txt","r");
                    fseek(searchfile, 0, SEEK_END); 
                    Size = ftell(searchfile); 
                    char *bufferfile = (char*)malloc(Size); 
                    memset(bufferfile, 0, Size); 
                    fseek(searchfile, 0, SEEK_SET); 
                    fread(bufferfile, Size, 1, searchfile); 
                    n = write(newsockfd,bufferfile,256);
                    fclose(searchfile); 
                }
            if(buffer[0]==docstring[0])
                {

                    FILE* searchfile = 0;
                    long Size = 0; 
                    searchfile = fopen("docfiles.txt","r");
                    fseek(searchfile, 0, SEEK_END); 
                    Size = ftell(searchfile); 
                    char *bufferfile = (char*)malloc(Size); 
                    memset(bufferfile, 0, Size); 
                    fseek(searchfile, 0, SEEK_SET); 
                    fread(bufferfile, Size, 1, searchfile); 
                    n = write(newsockfd,bufferfile,256);
                    fclose(searchfile); 
                }
            if(buffer[0]==photostring[0])
                {
                    FILE* searchfile = 0;
                    long Size = 0; 
                    searchfile = fopen("photofiles.txt","r");
                    fseek(searchfile, 0, SEEK_END); 
                    Size = ftell(searchfile); 
                    char *bufferfile = (char*)malloc(Size); 
                    memset(bufferfile, 0, Size); 
                    fseek(searchfile, 0, SEEK_SET); 
                    fread(bufferfile, Size, 1, searchfile); 
                    n = write(newsockfd,bufferfile,256);
                    fclose(searchfile); 
                }
            }
        if(buffer[0]==wrap[0])  
            {
                close(sockfd);
                close(newsockfd);
                johns = johns - 1;
                serverlogs("A john left");
                return 0;
            }   
    n = write(newsockfd,"\n Waiting for a command I can understand:(publish,search,get,exit)",66);

    } /* while loop to listen to commands from client bracket */
}/*what to do when client connected*/


} /*Creating child/zombies */
} /* division between client and server*/
else
{
    while (1)

    {int ssockfd, pportno, p,peer;
    struct sockaddr_in peer_addr;
    struct hostent *peerserver;
    char bbuffer[256];
    printf ("%s \n", "Welcome to the Social");
    printf ("%s \n", "Please type the port number of the server \n");
    cin>>pportno;
    ssockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    error("ERROR opening socket Please try again");
    printf ("%s \n", "Please type in the hostname of client ie sunlab1.njit.edu \n");
    char peers[256];
    cin >> peers;
    peerserver = gethostbyname(peers);
    if (peerserver == NULL)
    {
    fprintf(stderr,"could not connect to ip address");
    peerserver = gethostbyname((const char*)peer);
    if (peerserver == NULL)
    fprintf(stderr,"still null");
    exit(0);
    }
    bzero((char *) &peer_addr, sizeof(peer_addr));
    peer_addr.sin_family = AF_INET;
    bcopy((char *)peerserver->h_addr,(char *)&peer_addr.sin_addr.s_addr,peerserver->h_length);
    peer_addr.sin_port = htons(pportno);
    if (connect(ssockfd,(struct sockaddr *)&peer_addr,sizeof(peer_addr)) < 0)
    error("ERROR connecting");
    clientlogs("Connected to peer");
    clientlogs((const char*)&peer);
    printf("Please enter a command, publish,search or get: ");
    while (1)
    {
    bzero(bbuffer,256);
    fgets(bbuffer,255,stdin);
    char apub[] = "publish";
    char asearch[] = "search";
    char aget[]="get";
        if (bbuffer[0]==apub[0] && bbuffer[1]==apub[1])
            {   
                p = write(ssockfd,bbuffer,strlen(bbuffer));
                if (p < 0)
                error("ERROR writing to socket");
                bzero(bbuffer,256);
                p = read(ssockfd,bbuffer,255);
                if (p < 0)
                error("ERROR reading from socket");
                printf("%s",bbuffer); //What category are you publishing in//
                bzero(bbuffer,256);
                fgets(bbuffer,255,stdin);
                p = write(ssockfd,bbuffer,strlen(bbuffer));
                clientlogs("Client publishing");
                clientlogs(bbuffer);
                if (p < 0)
                error("ERROR writing to socket");
                bzero(bbuffer,256);
                p = read(ssockfd,bbuffer,255);
                if (p < 0)
                error("ERROR reading from socket");
                printf("%s",bbuffer); //Type the name of the file//
                fgets(bbuffer,255,stdin);
                p = write(ssockfd,bbuffer,strlen(bbuffer));
                clientlogs(bbuffer);
                FILE* searchfile = 0;
                long Size = 0; 
                searchfile = fopen(bbuffer,"r");
                fseek(searchfile, 0, SEEK_END); 
                Size = ftell(searchfile); 
                char *bufferfile = (char*)malloc(Size); 
                memset(bufferfile, 0, Size); 
                fseek(searchfile, 0, SEEK_SET); 
                fread(bufferfile, Size, 1, searchfile); 
                p = write(ssockfd,bufferfile,256);
                fclose(searchfile); 


                }

        if(bbuffer[0]==aget[0] && bbuffer[1]==aget[1])
        {       
                p = write(ssockfd,bbuffer,strlen(bbuffer));
                if (p < 0)
                error("ERROR writing to socket");
                bzero(bbuffer,256);
                p = read(ssockfd,bbuffer,255);
                if (p < 0)
                error("ERROR reading from socket");
                printf("%s",bbuffer); //What file do you want to get? //
                bzero(bbuffer,256);
                fgets(bbuffer,255,stdin);

                p = write(ssockfd,bbuffer,strlen(bbuffer));
                if (p < 0)
                error("ERROR writing to socket");
                clientlogs("client wants file:");
                clientlogs(bbuffer);
                /*start recieving a file*/

                std::ofstream file;
                file.open(bbuffer, std::ios::out | std::ios::binary);
                assert(file.is_open());
                char buffer[255];
                while (1) {
                std::cout << ".";
                bzero(bbuffer,256);
                p = read(ssockfd, bbuffer, sizeof(bbuffer));
                assert(p != -1);
                if (p == 0)
                break;
                file.write(bbuffer, p);
                            }
                file.close();
                serverlogs("File Transfered successfully");
            }

        if (bbuffer[0]==asearch[0] && bbuffer[1]==asearch[1])
        {
                p = write(ssockfd,bbuffer,strlen(bbuffer));
                if (p < 0)
                error("ERROR writing to socket");
                bzero(bbuffer,256);
                p = read(ssockfd,bbuffer,255);
                if (p < 0)
                error("ERROR reading from socket");
                printf("%s",bbuffer); // what category? //
                fgets(bbuffer,255,stdin);
                p = write(ssockfd,bbuffer,strlen(bbuffer));
                if (p < 0)
                error("ERROR writing to socket");
                clientlogs("Client searching for file");
                clientlogs(bbuffer);
                bzero(bbuffer,256);
                p = read(ssockfd,bbuffer,255);
                if (p < 0)
                error("ERROR reading from socket");
                printf("%s",bbuffer); //The vector array of the files // 

        }
        if (bbuffer[0]==wrap[0] && bbuffer[1]==wrap[1])
        {    p = write(ssockfd,bbuffer,strlen(bbuffer));    
                        exit(0);                     }


    }//end of client loop asking to enter a command

}




}


return 0;

}

1 个答案:

答案 0 :(得分:2)

我看到的问题是file << bbuffer。 ofstream的<<运算符写入直到第一个NULL字节。不要忘记你的缓冲区是一个字符串(或更好,char *)。因此,如果bbuffer不包含NULL字节,则您的程序可能会因SIGSEGV而崩溃。

您应该使用file.write(bbuffer, p)代替file << bbuffer。此外,无需使用bzeromemset清除缓冲区。

既然你没有提供可编译的源代码,我写了以下内容(假设是Linux / Unix):

#include <cassert>
#include <iostream>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main() {
    int fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in sa_dst;
    memset(&sa_dst, 0, sizeof(struct sockaddr_in));
    sa_dst.sin_family = AF_INET;
    sa_dst.sin_port = htons(1234);
    sa_dst.sin_addr.s_addr = inet_addr("127.0.0.1");

    int ret = connect(fd, (struct sockaddr *)&sa_dst, sizeof(struct sockaddr));
    assert(ret != -1);

    std::ofstream file;
    file.open("received.bin", std::ios::out | std::ios::binary);
    assert(file.is_open());
    char buffer[255];
    while (1) {
        std::cout << "..";
        ssize_t p = read(fd, buffer, sizeof(buffer));
        assert(p != -1);
        if (p == 0)
            break;
        file.write(buffer, p);
    }
    file.close();
}

您可以在终端上使用netcat进行测试:

$ nc -l 1234 < some_binary_file &
$ ./program
$ cmp some_binary_file received.bin