2014-03-13 113 views
1

我有下面的套接字代碼和客戶端代碼。到目前爲止,它所做的只是建立與服務器的連接,但我希望它也能將文件從客戶端發送到服務器;即使文件中沒有數據。我需要做些什麼才能增強此代碼以發送文件?代碼形式的任何建議?C中的套接字編程 - 從服務器發送文件到客戶端

客戶:

#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <arpa/inet.h> 

int main(int argc, char *argv[]) 
{ 
    int sockfd = 0, n = 0; 
    char recvBuff[1024]; 
    struct sockaddr_in serv_addr; 

    if(argc != 2) 
    { 
     printf("\n Usage: %s <ip of server> \n",argv[0]); 
     return 1; 
    } 

    memset(recvBuff, '0',sizeof(recvBuff)); 
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
     printf("\n Error : Could not create socket \n"); 
     return 1; 
    } 

    memset(&serv_addr, '0', sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_port = htons(5000); 

    if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0) 
    { 
     printf("\n inet_pton error occured\n"); 
     return 1; 
    } 

    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
    { 
     printf("\n Error : Connect Failed \n"); 
     return 1; 
    } 

    while ((n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0) 
    { 
     recvBuff[n] = 0; 
     if(fputs(recvBuff, stdout) == EOF) 
     { 
      printf("\n Error : Fputs error\n"); 
     } 
    } 

    if(n < 0) 
    { 
     printf("\n Read error \n"); 
    } 

    return 0; 
} 

服務器:

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/types.h> 
#include <time.h> 

int main(int argc, char *argv[]) 
{ 
    int listenfd = 0, connfd = 0; 
    struct sockaddr_in serv_addr; 

    char sendBuff[1025]; 
    time_t ticks; 

    listenfd = socket(AF_INET, SOCK_STREAM, 0); 
    memset(&serv_addr, '0', sizeof(serv_addr)); 
    memset(sendBuff, '0', sizeof(sendBuff)); 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serv_addr.sin_port = htons(5000); 

    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 

    listen(listenfd, 10); 

    while(1) 
    { 
     connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 

     ticks = time(NULL); 
     snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks)); 
     write(connfd, sendBuff, strlen(sendBuff)); 

     close(connfd); 
     sleep(1); 
    } 
} 

回答

0

我沒有帶試着編譯這個,還有這個代碼是肯定不是粗糙,但類似的東西下面會做的伎倆:)

修改客戶端看起來像這樣:

if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
{ 
    printf("\n Error : Connect Failed \n"); 
    return 1; 
} 

FILE *inputFile = fopen("inputFile.txt", "rb"); 

if(inputFile == NULL) 
{ 
    fprintf(stderr, "oh no!"); 
    return 1; 
} 

char sendBuffer[10]; 

// TODO: Check for errors here 
int bytesRead = fread(sendBuffer, sizeof(sendBuffer), 1, inputFile); 

while(!feof(inputFile)) 
{ 
    //TODO: check for errors here 
    send(sockfd, sendBuffer, bytesRead, 0); 
    bytesRead = fread(sendBuffer, sizeof(sendBuffer), 1, inputFile); 
} 
close(sockfd); 

修改服務器端是這樣的:

listen(listenfd, 10); 

FILE *outputFile = fopen("output.txt", "wb"); 

if(outputFile == null) 
{ 
    fprintf(stderr, "Something went south!"); 
    return 1; 
} 

while(1) 
{ 
    connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 

    char recvBuff[10]; 

    ticks = time(NULL); 
    int bytesReceived = recv(confd, recvBuff, 10, 0); 
    while(bytesReceived != 0) 
    { 

     // you should add error checking here 
     fwrite(recvBuff, bytesReceived, 1, outputFile); 

     bytesReceived = recv(confd, recvBuff, 10, 0); 
    } 

    close(connfd); 
} 
+0

如果你想使這個非常好的,以及固定我的馬虎的代碼,你可以製作成多線程版本和服務器創建一個新的線程爲它收到的每個客戶端請求。如果你還沒有學過關於線程的知識,那麼就沒關係,這將會很好,但一次只能爲一個客戶端。 –

+0

學習這種類型的東西的一個好方法是找到一本好書。我強烈推薦Graham Glass的「Unix for programmers and users」(http://www.amazon.com/UNIX-Programmers-Users-3rd-Edition/dp/0130465534) –

+0

謝謝@NickWeedon。它只需要一次處理一個文件,因此多個線程並不是真的需要。我也忘了提及它應該能夠處理沒有數據的文件。這會解釋嗎?還是應該修改發送和接收? –

相關問題