sourcecode

읽기() 및 쓰기() 함수는 C의 로컬 연결(같은 컴퓨터) 상의 TCP 연결 중에 -1을 반환합니다.

copyscript 2022. 9. 16. 23:03
반응형

읽기() 및 쓰기() 함수는 C의 로컬 연결(같은 컴퓨터) 상의 TCP 연결 중에 -1을 반환합니다.

클라이언트에서 서버로 파일 내용을 전송하기 위한 코드를 작성했습니다.이것은 서버측의 특정 파일을 갱신하는 것을 의미합니다.이 순서는 사용자 입력에 따라 N초마다 계속됩니다.그러나 다음과 같은 오류가 발생했습니다.

로컬 접속(같은 컴퓨터)에서도 write() 및 read() 함수는 파일 전송 중에 -1을 반환합니다.이 문제는 때때로 나타나지 않을 수도 있습니다.그러나 사용자가 더 큰 파일(30MB 이상)을 전송할 때 더 많이 나타납니다.그 결과, 이 문제는 분명히 그것을 촉발시킬 무언가를 기다리고 있는 것입니다.이것은 어떤 프로그램에서도 매우 불편한 양상입니다.예를 들어 sleep() 함수를 1초간 기다렸다가 소켓에서 write()/read()를 사용하면 이 문제가 발생하지 않습니다.왜 이런 일이 일어나는지, 어떻게 하면 고칠 수 있는지 설명해 주세요.또한 다른 모든 코드에서는 read() 또는 write()가 연결 중에 -1을 반환하는 경우 exit(0)만 표시됩니다.지도해 주셔서 감사합니다

아쉽게도 비슷한 질문에서는 해결책을 찾을 수 없었습니다.왜 그런 문제가 발생했는지, 어떻게 해결할 수 있는지 설명해 주시면 감사하겠습니다.고객님의 편의를 위해 아래 절차에 대해 자세히 설명했습니다.

  1. 이 코드의 주된 아이디어는 정기적으로 갱신되는 파일에서 데이터를 전송하는 것입니다.그 결과, N초마다 서버에 나머지 데이터를 전송해야 합니다.
  2. 서버(서버)와 클라이언트(클라이언트)는 서로 접속합니다(고객님과 같은 프로 사용자에게 새로운 것은 없습니다).
  3. server(서버)가 보관 유지되는 데이터의 양을 송신하고, 유저는 남아 있는 데이터의 양을 계산합니다.이 절차를 수행하면 서버와 클라이언트 모두 현재 반복 시 전송해야 하는 데이터 양을 알 수 있습니다.
  4. 클라이언트는 나머지 데이터를 모두 cacheBuffer로 읽고 파일을 닫습니다.(cacheBuffer는 나머지 바이트와 동일하며 클라이언트와 서버 모두에서 작동합니다.)
  5. 메인(내부) while loop에서는 cacheBuffer에서 mssg 구조로 복사하고 나중에 소켓을 통해 구조를 전송합니다.
  6. 마찬가지로 클라이언트 내부의 while 루프는 구조 mssg를 읽고 데이터를 캐시 버퍼에 복사합니다.
  7. 마지막으로, 송수신 종료시에, 수신측(서버)이 캐시 버퍼의 내용을 타겟 파일에 기입해, 처리를 속행한다.

클라이언트 코드

/*
    How to compile ->
    (1) make all
        if no make was provided then gcc server.c utilityFunctionsMHZ.h -o server
    (2) ./server FILENAME PORT_NUMBER SLEEP_TIMER MAX_BUFFER_SIZE
        Example: ./server mainFile2.log 5500 10 4096
    (3) ./client FILENAME SERVER_ADDR PORT_NUMBER 
        Example: ./client mainFile.log 172.17.34.89 5500
*/  

#include "utilityFunctionsMHZ.h"

int main (int argc, char* argv[])
{
    // Initial Error Check And Call Initializer
    if (argc < 4) 
    {   
        fprintfSwitchable(NULL, 0, "[+client] Please use the given format: ./client FILENAME SERVER_ADDR PORT_NUMBER\n");
        exit(0);
    }
    else if (!isFileAvailable(argv[1], "client", NULL))
    {
        exit(0);
    }
    else
    {
        Initializer ("client", NULL);
        fprintfSwitchable(NULL, 0, "[+%s] Make Sure to Run server First.\n", "client");
    }
        
    // Input Parameters  
    const char* fileLocFull = argv[1];
    char* serverIP          = argv[2];
    int portNumber          = atoi(argv[3]);

    // Buffer & Cache Properties and Size 
    struct bufferTCP* mssg = CreateBufferTCP();
    size_t MAX_CACHE_SIZE, CACHE_SIZE;
    char* cacheBuffer;

    // File Process, Data Structure (NACK-Sender & ACK-Reciever)
    FILE* filePtr_NACK;
    size_t fileMemory_NACK = 0;
    size_t fileMemory_ACK = 0;
    size_t fileRemainMemory = 0;

    // Create Socket via TCP Protocol & Error Check
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1)
        fprintfSwitchable(NULL, 1, "[-client] Error in Socket Initiation!\n");
    else
        fprintfSwitchable(NULL, 0, "[+client] Socket Successfully Initiated.\n");
    // Socket main Structures
    struct sockaddr_in* serverAddr = malloc(sizeof(struct sockaddr_in));
    
    // Socket Structures Memory Allocation Test
    if (serverAddr == NULL) 
        fprintfSwitchable(NULL, 1, "[-client] Memory Allocation for sockadd_in strctures Failed!\n");
    else
        fprintfSwitchable(NULL, 0, "[+client] Memory Allocation for sockadd_in strctures Successfully Completed.\n");
    
    // Set-up server parameters
    bzero(serverAddr, sizeof(struct sockaddr_in));   //memset(serverAddr, 0x00, sizeof(struct sockaddr_in));
    serverAddr->sin_family      = AF_INET;
    //serverAddr->sin_addr.s_addr = inet_addr(serverIP);
    inet_pton(AF_INET, serverIP, &(serverAddr->sin_addr));
    serverAddr->sin_port        = htons(portNumber);

    // Connection Request to Server
    if (connect(sockfd, (struct sockaddr*) serverAddr, sizeof(struct sockaddr_in)) == -1)
        fprintfSwitchable(NULL, 1, "[-client] Error in Connecting to Server!\n");
    else
        fprintfSwitchable(NULL, 0, "[+client] Connection Successfully Accepted.\n");

    if (read(sockfd, &MAX_CACHE_SIZE, sizeof(size_t)) == -1)
        fprintfSwitchable(NULL, 1, "[-client] Error in MAX CACHE Size Negitiation!\n"); 
    else 
        fprintfSwitchable(NULL, 0, "[+client] CACHE Size is Set Equal to Server: %lu.\n", MAX_CACHE_SIZE);
    
    // Initializing Sender Sleep Clock
    size_t sleepTimer;
    if (read(sockfd, &sleepTimer, sizeof(size_t)) == -1)
        fprintfSwitchable(NULL, 1, "[-client] Error in Sleep Timer Negitiation!\n", 1, 1); 
    else 
        fprintfSwitchable(NULL, 0, "[+client] Sleep Timer is Set Equal to Server: %lu\n", sleepTimer); 
    
    int iack;
    int ACKFLAG = 0;
    size_t OveralIteration = 0;
    size_t SentBytes;
    size_t Not_Written = 0;
    ssize_t readFLAG;
    ssize_t writeFLAG;
    size_t InnerIteration = 0;

    fprintfSwitchable(NULL, 0, "**********************Client-Side::Sending Started**************************\n"); 
    while (1)
    {
        fileMemory_NACK = FileSizeCalculator(fileLocFull);

        // File Status @ Server (Reciever) 
        if (read(sockfd, &fileMemory_ACK, sizeof(size_t)) == -1)
            fprintfSwitchable(NULL, 1, "[-client] Error in reading File Info!\n"); 
        else
            fprintfSwitchable(NULL, 0, "[+client] File (Size) Info is Recieved Successfully.\n"); 

        // Send-Recieve Validity
        fileRemainMemory = fileMemory_NACK - fileMemory_ACK;
            
        // Send Expecting Data Size For Server
        if (write(sockfd, &fileRemainMemory, sizeof(size_t)) == -1)
            fprintfSwitchable(NULL, 1, "[-client] Failed To Send Remaining Memory Info!\n"); 
        else
            fprintfSwitchable(NULL, 0, "[+client] Session [%lu] Overview: \nACK Memory is %lu\nNACK Memory is %lu\nRemaining Memory is: %lu\n\n", 
                                        OveralIteration, fileMemory_ACK, fileMemory_NACK, fileRemainMemory); 
        // Assess Sending
        if (fileMemory_NACK == fileMemory_ACK) 
        {
            fprintfSwitchable(NULL, 0, "[+client] Remaining Memory is Zero. Send Process Will Contine After %lu[s] Timeout.\n", sleepTimer);;  
            continue;
        }
        else if (fileRemainMemory < BUFFER_MAX)
        {
            fprintfSwitchable(NULL, 0, "[+client] Remaining Buffer is Smaller Than Cache Limit %lu. Send Process Will Contine After %lu[s] Timeout.\n",
                              BUFFER_MAX, sleepTimer);  
            Not_Written++;
            if (Not_Written < 10) 
                continue;
            else
                Not_Written = 0;
        }
        
        // Creating Cache
        CACHE_SIZE = fileRemainMemory;
        cacheBuffer = (char*) calloc (CACHE_SIZE, sizeof(char));
        bzero(cacheBuffer, CACHE_SIZE);
        
        // Copy Data From File to CACHE-Buffer
        filePtr_NACK = fopen(fileLocFull, "r");
        fseek(filePtr_NACK, fileMemory_ACK, SEEK_SET);
        fread(cacheBuffer, sizeof(char), CACHE_SIZE, filePtr_NACK);
        fclose(filePtr_NACK);
        
        ACKFLAG = 0;
        SentBytes = 0;
        fileRemainMemory = CACHE_SIZE;
        InnerIteration = 0;
        while (1)
        {
            // EXIT CONDITION
            if (fileRemainMemory == 0) break;
            
            // Evaluate Buffer Size
            if (fileRemainMemory >= BUFFER_MAX)                     
                mssg->BUFFER_USED = BUFFER_MAX;
            else 
                mssg->BUFFER_USED = fileRemainMemory;
                
            // Copy From CACHE to Socket Buffer and Send
            memcpy(mssg->mssgPtr, cacheBuffer+SentBytes, mssg->BUFFER_USED);
            writeFLAG = write(sockfd, mssg, sizeof(struct bufferTCP)); 
            fprintfSwitchable(NULL, 0, "[+client] Iter %ld :: %ld/%ld Sent!\n", InnerIteration++, writeFLAG, sizeof(struct bufferTCP)); 
            // Cases:
            if (writeFLAG == -1)
            {
                // Display Problem
                fprintfSwitchable(NULL, 0, "[-client] Error While Sending Buffer!\n");
                fprintfSwitchable(NULL, 0, "[-client] %s\n", strerror(errno));
            } 
            else if (writeFLAG < sizeof(struct bufferTCP))
            {
                // Display Problem
                fprintfSwitchable(NULL, 0, "[-client] Only %ld/%ld Sent!\n", writeFLAG, sizeof(struct bufferTCP)); 
            }   
            else
            {
                // In Session Statistics    
                fileRemainMemory -= mssg->BUFFER_USED;
                SentBytes        += mssg->BUFFER_USED;
                fprintfSwitchable(NULL, 0, "[+client] (%lu) Current-Iteration | (%lu) Total-Sent | (%lu) Remaining.\n", writeFLAG, SentBytes, fileRemainMemory);
            }   
            bzero(mssg->mssgPtr, BUFFER_MAX); 
        }
        if (writeFLAG != -1 && fileRemainMemory == 0)
        {
            fileMemory_ACK = SentBytes;
            OveralIteration++;
        }
            
        // Session Summary
        fprintfSwitchable(NULL, 0, "[+client] Session %lu Summary:\nACK Memory is %lu :: Remaining Memory is: %lu\n\n", 
                                          OveralIteration, fileMemory_ACK, fileRemainMemory);   
        free(cacheBuffer);
        // Exit Condition
        if (isEnd (sleepTimer, "client"))  break;

    }
    fprintfSwitchable(NULL, 0, "\n***********************Client-Side::Sending Ended***************************\n"); 

    close(sockfd);
    free(serverAddr);
    free(mssg);

    return 0;
}

서버 코드:


/*
    How to compile ->
    (1) make all
        if no make was provided then gcc server.c utilityFunctionsMHZ.h -o server
    (2) ./server FILENAME PORT_NUMBER SLEEP_TIMER CHACHE_SIZE_MAX
        Example: ./server mainFile2.log 5500 10 4096
    (3) ./client FILENAME SERVER_ADDR PORT_NUMBER
        Example: ./client mainFile.log 172.17.34.89 5500
*/  

#include "utilityFunctionsMHZ.h"

int main (int argc, char* argv[])
{
    // Initial Error Check And Call Initializer
    if (argc < 5) 
    {
        fprintfSwitchable(NULL, 0, "[+server] Please use the following format to initiate the ./server FILENAME PORT_NUMBER SLEEP_TIMER MAX_CACHE_SIZER\n");
        exit(0);
    }   
    else
    {
        Initializer ("server", NULL);
    }
        
    // Input Parameters  
    const char* fileLocFull = argv[1];
    int portNumber          = atoi(argv[2]);         
    size_t sleepTimer       = atoi(argv[3]); 
    size_t MAX_CACHE_SIZE   = atoi(argv[4]);
    size_t WaitQueue        = 5;
    
    // server :: Socket Accept Client Request
    socklen_t socklen = sizeof(struct sockaddr_in);

    // File Process, Data Structure (NACK is the Sender/Client Side)
    if (!isFileAvailable(argv[1], "server", NULL))
    {
        FILE* filePtr_ACK = fopen(fileLocFull, "w");
        fclose(filePtr_ACK);
    }
    
    //size_t checker = FileCorrector (fileLocFull);
    size_t checker = FileModifier (fileLocFull);

    // File Process, Data Structure (NACK-Sender & ACK-Reciever)
    FILE* filePtr_ACK;
    size_t fileMemory_ACK = 0;
    size_t fileRemainMemory = 0;
    
    // Buffer Properties and Size (Set Sender/Client Buffer-Size Equal to Server)
    struct bufferTCP* mssg = CreateBufferTCP();
    // Cache properties
    size_t CACHE_SIZE;
    char* cacheBuffer;

    // socket End-Point
    int sockfd, sockfd_new;
    // client :: Initiation Socket via TCP Protocol & Error Check
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1)
        fprintfSwitchable(NULL, 1, "[-server] Error in Socket Initiation!\n");
    else
        fprintfSwitchable(NULL, 0, "[+server] Socket Successfully Initiated.\n");

    // Socket main Structures
    struct sockaddr_in* serverAddr;
    struct sockaddr_in* clientAddr;
    serverAddr =  malloc(sizeof(struct sockaddr_in));       
    clientAddr =  malloc(sizeof(struct sockaddr_in));
    
    // Socket Structures Memory Allocation Test
    if (clientAddr == NULL || serverAddr == NULL)
        fprintfSwitchable(NULL, 1, "[-server] Memory Allocation for sockadd_in strctures Failed!\n");
    else
        fprintfSwitchable(NULL, 0, "[+server] Memory Allocation Successfully Completed.\n");
    
    bzero(serverAddr, sizeof(struct sockaddr_in)); //memset(serverAddr, 0x00, sizeof(struct sockaddr_in));
    bzero(clientAddr, sizeof(struct sockaddr_in)); //memset(clientAddr, 0x00, sizeof(struct sockaddr_in));
    
    // set-up Server parameters
    serverAddr->sin_family      = AF_INET;
    serverAddr->sin_addr.s_addr = INADDR_ANY;   // inet_addr(clientIP);
    serverAddr->sin_port        = htons(portNumber);

    // server :: Socket Binding
    if (bind(sockfd, (struct sockaddr*) serverAddr, sizeof(struct sockaddr_in)) == -1)
        fprintfSwitchable(NULL, 1, "[-server] Error in Socket Binding!\n");
    else
        fprintfSwitchable(NULL, 0, "[+server] Socket Successfully Binded.\n");
    
    // server :: Socket Listening
    if (listen(sockfd, WaitQueue) == -1)
        fprintfSwitchable(NULL, 1, "[-server] Error while Listening!\n");
    else
        fprintfSwitchable(NULL, 0, "[+server] Listening...\n");
    
    // server :: Socket Listening
    sockfd_new = accept(sockfd, (struct sockaddr*) clientAddr, &socklen);
    if (sockfd_new == -1)
        fprintfSwitchable(NULL, 1, "[-server] Error in Accepting Client Connection!\n");
    else
        fprintfSwitchable(NULL, 0, "[+server] Connection Successfully Accepted.\n");

    // Establishing BUFFER_MAX_SIZE (Set Sender/Client Buffer-Size Equal to Server)
    if (write(sockfd_new, &MAX_CACHE_SIZE, sizeof(size_t)) == -1)
        fprintfSwitchable(NULL, 1, "[-server] Error in Buffer Size Negitiation!\n");
    else 
        fprintfSwitchable(NULL, 0, "[+server] MAX Buffer-Size is Sent to client: %lu.\n", MAX_CACHE_SIZE);
    
    // Initializing Sender Sleep Clock (Set Sender/Client Buffer-Size Equal to Server)
    if (write(sockfd_new, &sleepTimer, sizeof(size_t)) == -1)
        fprintfSwitchable(NULL, 1, "[-server] Error in Sleep Timer Negitiation!\n");
    else 
        fprintfSwitchable(NULL, 0, "[+server] Sleep-Timer is Sent to client: %lu\n", sleepTimer);

    int ACKFLAG = 0, CONFLAG = 0;
    size_t OveralIteration = 0;
    size_t SentBytes;
    size_t Not_Written;
    int iack = 0;
    ssize_t readFLAG;
    ssize_t writeFLAG;
    size_t InnerIteration = 0;

    fprintfSwitchable(NULL, 0, "**********************Server-Side::Recieving Started**************************\n");
    while (1)
    {
        // File Status @ Server (Reciever) 
        fileMemory_ACK = FileSizeCalculator(fileLocFull);
        
        // Send ACK Status
        if (write(sockfd_new, &fileMemory_ACK, sizeof(size_t)) == -1)
            fprintfSwitchable(NULL, 1, "[-server] Error in Sending File Info!\n");
        else
            fprintfSwitchable(NULL, 0, "[+server] File (Size) Info Sent Successfully.\n"); 

        // Recieve Expecting Data Size From Client
        if (read(sockfd_new, &fileRemainMemory, sizeof(size_t)) == -1)
            fprintfSwitchable(NULL, 1, "[-server] Failed to Recieve Remaining Memory Info!\n"); 
        else
            fprintfSwitchable(NULL, 0, "[+server] Session [%lu] Overview:\nACK Memory is: %lu\nRemaining Memory is: %lu\n\n", 
                                    OveralIteration, fileMemory_ACK, fileRemainMemory); 
        if (fileRemainMemory == 0) 
        {
            fprintfSwitchable(NULL, 0, "[+server] Remaining Memory is Zero. Process Will Contine After %lu[s] Timeout.\n", sleepTimer); 
            continue;
        }
        else if (fileRemainMemory < BUFFER_MAX)
        {
            fprintfSwitchable(NULL, 0, "[+server] Remaining Buffer is Smaller Than Cache Limit %lu. Recieve Process Will Contine After %lu[s] Timeout.\n",
                              BUFFER_MAX, sleepTimer);  
            Not_Written++;
            if (Not_Written < 10) 
                continue;
            else
                Not_Written = 0;
        }

        // Creating Cache
        CACHE_SIZE = fileRemainMemory;
        cacheBuffer = calloc (CACHE_SIZE, sizeof(char));
        bzero(cacheBuffer, CACHE_SIZE);

        ACKFLAG = 0;
        SentBytes = 0;
        fileRemainMemory = CACHE_SIZE;
        InnerIteration = 0;
        while (1)
        {
            // EXIT CONDITION
            if (fileRemainMemory == 0) break;

            // Recieve Buffer
            readFLAG = read(sockfd_new, mssg, sizeof(struct bufferTCP));    
            fprintfSwitchable(NULL, 0, "[+server] Iter %ld :: %ld/%ld Sent!\n", InnerIteration++, readFLAG, sizeof(struct bufferTCP)); 
            // Cases:
            if (readFLAG == -1) 
            {
                // Display Problem
                fprintfSwitchable(NULL, 0, "[-server] Error While Reading Buffer Size!\n"); 
            }
            else if (readFLAG < sizeof(struct bufferTCP))
            {
                // Copy From CACHE to Socket Buffer
                fprintfSwitchable(NULL, 0, "[-server] Only %ld/%ld Recieved!\n",readFLAG, sizeof(struct bufferTCP)); 
                fprintfSwitchable(NULL, 0, "[-server] %s\n", strerror(errno));
            }
            else
            {
                // Copy From CACHE to Socket Buffer
                memcpy(cacheBuffer+SentBytes, mssg->mssgPtr, mssg->BUFFER_USED);
                // In Session Statistics    
                fileRemainMemory -= mssg->BUFFER_USED;
                SentBytes        += mssg->BUFFER_USED;
                fprintfSwitchable(NULL, 0, "[+server] (%lu) Current-Iteration | (%lu) Total-Sent | (%lu) Remaining.\n", readFLAG, SentBytes, fileRemainMemory);
            }   
            bzero(mssg->mssgPtr, BUFFER_MAX); 
        }       
        if (readFLAG != -1 && fileRemainMemory == 0)
        {
            fileMemory_ACK = SentBytes;
            // Copy Data From File to CACHE-Buffer
            filePtr_ACK = fopen(fileLocFull, "a");
            fwrite(cacheBuffer, sizeof(char), CACHE_SIZE, filePtr_ACK);
            fclose(filePtr_ACK);
            OveralIteration++;
        }
        
        // Session Summary-alIteration, fileMemory_ACK, fileRemainMemory);  
        free(cacheBuffer);
        // Exit Condition
        if (isEnd (sleepTimer, "server"))  break;
    }
    fprintfSwitchable(NULL, 0, "\n***********************Server-Side::Recieving Ended***************************\n");
    
    close(sockfd);
    close(sockfd_new);
    free(serverAddr);
    free(clientAddr);
    free(mssg);

    return 0;
}

사용된 라이브러리


#ifndef utilityFunctionsMHZ_H
#define utilityFunctionsMHZ_H

#include <stdio.h>      //:: standard IO c-functions
#include <string.h>     //:: standard c-string functions
#include <unistd.h>     //:: standard POSIX operating system API (read/write/send/recv)
#include <stdlib.h>     //:: standard ALLOC c-functions (malloc, atoi)
#include <sys/types.h>  //:: definitions of data types used in sys/socket & netinet/in
#include <sys/socket.h> //:: definitions of structures needed for internet domain such as (struct sockaddr)
#include <netinet/in.h> //:: definitions of (struct sockaddr_in)
#include <netdb.h>      //:: definitions of (struct hostnet) to store info of a given host & IPV-4
#include <arpa/inet.h>  //:: inet()
#include <sys/stat.h>
#include <stdarg.h>     //:: Variable Input function
#include <errno.h>
#define BUFFER_MAX 1024

struct bufferTCP
{
    char mssgPtr[BUFFER_MAX];
    size_t BUFFER_USED;
};

// Usefull functions
struct bufferTCP* CreateBufferTCP();
void WriteLog(const char* logFileName, const char* mssg);
size_t FileCorrector (const char* fileName);;
FILE* FileOpenSafe (const char* fileName, const char* rwaMode);
size_t FileSizeCalculator (const char* fileName);
void fprintfSwitchable(FILE* stream, int errFlag, const char* mssg, ...);
FILE* FileOpenSafe (const char* fileName, const char* rwaMode);
size_t FileSizeCalculator (const char* fileName);
size_t FileCorrector (const char* fileName);
size_t FileModifier(const char* fileName);
void Initializer (const char* caller, FILE* stream);
int isEnd (size_t sleepTimer, const char* caller);
int isFileAvailable (const char* fileLocFull, const char* caller, FILE* stream);

void WriteLog(const char* logFileName, const char* mssg)
{
    FILE* logFilePtr = fopen(logFileName, "a");
    //fputs(mssg, logFilePtr);
    fclose(logFilePtr);
}


void fprintfSwitchable(FILE* stream, int errFlag, const char* mssg, ...)
{
    va_list args;

    va_start(args, mssg);

    if (stream == NULL)
    {
        vfprintf(stdout, mssg, args);
        fflush(stdout);
    }
    else
    {
        vfprintf(stream, mssg, args);
        fflush(stream);
    }    

    if (errFlag)  exit(1);
        
    va_end(args);
}


FILE* FileOpenSafe (const char* fileName, const char* rwaMode)
{
    if (fileName == NULL)
        fprintfSwitchable(NULL, -1, "FileName or Location is Incorrect!\n");

    FILE* filePtr = fopen(fileName, rwaMode);

    if (filePtr == NULL)
        fprintfSwitchable(NULL, -1, "File Location is Invalid Or File Does Not Exists!\n");

    return filePtr;
}


size_t FileSizeCalculator (const char* fileName)
{
    FILE* filePtr = FileOpenSafe(fileName, "r");
    int fileDescriptor = fileno(filePtr);
    struct stat fileInfo;
    bzero(&fileInfo, sizeof(struct stat));
    fstat(fileDescriptor, &fileInfo);
    size_t fileSize =  fileInfo.st_size;
    fclose(filePtr);

    return fileSize;
}

size_t FileCorrector (const char* fileName)
{
    size_t fileSize = FileSizeCalculator (fileName);
    size_t fileSizeTrue;
    if (fileSize == 0)
    {
        fprintfSwitchable(NULL, 0, "File is Empty, thus requires no correction!\n");
        return 0;
    }
        
    // Main & Temp File
    FILE* mainFile = FileOpenSafe (fileName, "r");
    FILE* tempFile = FileOpenSafe("temp", "w");
    
    // Fault Detection (\00 0\0 00) and correct
    char checkBuff[3];
    char curserrChar;
    
    size_t ii;
    for (ii = 0; ii < fileSize; ii++)
    {
        curserrChar = fgetc(mainFile);
        //printf("%c", curserrChar);
        if (curserrChar == '\00')
        {    
            fileSizeTrue = ftell(mainFile)-2;
            break;
        }
        fputc(curserrChar, tempFile);
    }
    fclose(mainFile);
    fclose(tempFile);

    // Remove The Old File
    if (remove(fileName) == 0) 
        fprintfSwitchable(NULL, 0, "Faulty File (%s) Removed Successfully.\n", fileName);
    else
        fprintfSwitchable(NULL, 1, "Error while Removing the Faulty File: %s!\n", fileName);


    // Remove The Old File
    if (rename("temp", fileName) == 0) 
        fprintfSwitchable(NULL, 0, "Corrected File Renamed Successfully.\n");
    else
        fprintfSwitchable(NULL, 1, "Error while Removing the Faulty File: %s!\n");

    fprintfSwitchable(NULL, 0, "Correction Implemented Successfully.\n");

    return fileSizeTrue;
}


size_t FileModifier(const char* fileName)
{
    size_t fileSize = FileSizeCalculator (fileName);
    size_t fileSizeTrue;
    if (fileSize == 0)
    {
        fprintfSwitchable(NULL, 0, "[+server] File is Empty, thus requires no correction.\n");
        return 0;
    }
        
    // Main & Temp File
    FILE* mainFile = FileOpenSafe (fileName, "r");
    FILE* tempFile = FileOpenSafe("temp", "w");
    
    // Fault Detection (\00 0\0 00) and correct
    char checkBuff[3];
    char curserrChar;
    size_t ii;
    for (ii = 0; ii < fileSize; ii++)
    {
        curserrChar = fgetc(mainFile);
        if (curserrChar == '\00') break;
        fputc(curserrChar, tempFile);
    }
    fclose(mainFile);
    fclose(tempFile);


    mainFile = FileOpenSafe (fileName, "w");
    tempFile = FileOpenSafe("temp", "r");
    fileSizeTrue = FileSizeCalculator ("temp");

    ii=0;
    for (ii = 0; ii < fileSizeTrue; ii++)
    {
        curserrChar = fgetc(tempFile);
        fputc(curserrChar, mainFile);
    }
    
    fclose(mainFile);
    fclose(tempFile);

    // Remove The Old File
    if (remove("temp") == 0) 
        fprintfSwitchable(NULL, 0, "[+server] Temp File Removed Successfully.\n");
    else
        fprintfSwitchable(NULL, 1, "[-server] Error while Removing the Faulty File!\n");

    fprintfSwitchable(NULL, 0, "[+server] File Modifier Executed Successfully.\n");

    return fileSizeTrue;
}


void Initializer (const char* caller, FILE* stream)
{
    // Initial confirmation client side
    char checkSend;
    fprintfSwitchable(stream, 0, "[+%s] Start Process [Y/N]: ", caller);
    scanf(" %c", &checkSend);
    if (checkSend == 'N' || checkSend == 'n')
    {
        fprintfSwitchable(stream, 0, "[-%s] Abort Process As Requested!\n", caller);
        exit(0);
    } 
    else
        return;
}
    
int isEnd (size_t sleepTimer, const char* caller)
{
    // Exit Material
    fd_set          s;
    struct timeval  timeout;
    char exitFlag[12];
    memset(&exitFlag, 'F', 12);
    int sFlag;

    fflush(stdout);
    FD_ZERO(&s);
    FD_SET(0, &s);
    timeout.tv_sec = sleepTimer; timeout.tv_usec = 0;
    sFlag = select(1, &s, NULL, NULL, &timeout);
    
    if      (sFlag < 0) 
        return 0;
    else if (sFlag == 0) 
    {
        fflush(stdout);
        fprintfSwitchable(NULL, 0, "-\n");
        return 0;
    }
    else
    {
        fgets(exitFlag, 12, stdin);
        fprintfSwitchable(NULL, 0, "[+%s] To Quit, please enter \"exit\": ", caller); 
        fflush(stdout);
        if ( memcmp(&exitFlag, "exit", 4) == 0 ) 
            return 1;
        else
            return 0;
    }

}

int isFileAvailable (const char* fileLocFull, const char* caller, FILE* stream)
{
    // Checks if The Target Send File Exists!
    FILE* filePtr_NACK = fopen(fileLocFull, "r");
    if (filePtr_NACK == NULL)
    {
        fprintfSwitchable(stream, 0, "[-%s] Not Such File Name Exists!\n", caller);
        return 0;
    }
    else
    {
        fprintfSwitchable(stream, 0, "[+%s] File Found Successfully.\n", caller);
        fclose(filePtr_NACK);
        return 1;
    }
    
}


void copyWithOffsetDest(char* dest, const char* src, size_t start, size_t length)
{
    size_t i = 0;
    for (i = 0; i < length; i++)
        dest[start+i] = src[i];
}

void copyWithOffsetSource(char* dest, const char* src, size_t start, size_t length)
{
    size_t i = 0;
    for (i = 0; i < length; i++)
        dest[i] = src[i+start];
}


struct bufferTCP* CreateBufferTCP()
{
    struct bufferTCP* mssg = (struct bufferTCP*) 
                malloc(sizeof(struct bufferTCP));
    return mssg;
}

#endif

파일 만들기

all:    client server

ftpclient: client.c
    gcc -std=gnu99 -Wall $< -o $@

ftpserver: server.c
    gcc -std=gnu99 -Wall $< -o $@

clean:
    rm -f client server *.o *~ core
    rm server client

언급URL : https://stackoverflow.com/questions/73597713/read-and-write-functions-return-1-during-a-tcp-connection-on-local-connecti

반응형