2012-06-27 11 views
5

まず最初に、これを読んで助けてくれてありがとう、とても感謝しています。
2回目も申し訳ありませんが、私はまだこのサイトを初めて利用しており、英語は母国語ではないため、書式設定や言語間違いをする可能性があります。私は事前に謝罪します。
また、Cの知識はそれほど良くはありませんが、私は喜んで学び、改善しています。
今、手元に:Unix上のソケットを使ってCでファイル(サーバ/クライアント)を送受信する

私がする必要があるのは、クライアントとサーバーを作成し、サーバーに着信接続をリッスンさせることです。
それから、私はクライアントがサーバーに非常に大きなテキストファイル(私はそれが1つだけのファイルであることを知っている)を送ります。
サーバーはそのファイルに対して何らかの操作を行います(出力ファイルに "output.txt"という別のファイルを生成するスクリプトを実行します)。 その後、サーバーはoutput.txtファイルをクライアントに送り返す必要があります。

今、私はちょっとした間違いをしたとしても、クライアントとサーバー(私はこのサイトでbeejガイドやその他のものを読んでいます)を作る方法を知っています。私は、ファイルを受信したサーバーでいくつかの助けを必要とし、スクリプトを呼び出して、他のファイルをクライアントに送り返します。 今のところ、私がやったことはサーバーとクライアントです...私は実際にどのように進むべきか分かりません。
私はこのサイトとインターネット上で見つけたものを使ってこのファイルを作ったが、私はプログラマーにはそれほど良くないので、あまり面倒ではないと思う。私は上に行く方法についていくつかのポインタを希望

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <signal.h> 
#include <pthread.h> 

#define SOCKET_PORT 50000 
#define filename "/home/aryan/Desktop/output.txt" 


void error(const char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 

void* client_thread_proc(void* arg) 
{ 
char buffer[256]; 
struct sockaddr_in serv_addr, cli_addr; 
int n; 
FILE *fp; 

int thisfd = (int)arg; 
printf("Server %d: accepted = %d\n", getpid(), thisfd); 

if (thisfd < 0) 
{ 
    printf("Accept error on server\n"); 
    error("ERROR on accept"); 
    return NULL; 
} 

printf("Connection %d accepted\n", thisfd); 

fp = fopen(filename, "a+b"); 
if (fp == NULL) 
{ 
    printf("File not found!\n"); 
    return NULL; 
} 
else 
{ 
    printf("Found file %s\n", filename); 
} 

/* Time to Receive the File */ 
while (1) 
{ 
    bzero(buffer,256); 
    n = read(thisfd,buffer,255); 
    if (n < 0) error("ERROR reading from socket"); 

    n = fwrite(buffer, sizeof(char), sizeof(buffer), fp); 
    if (n < 0) error("ERROR writing in file"); 

    n = write(thisfd,"I am getting your file...",25); 
    if (n < 0) error("ERROR writing to socket"); 
} /* end child while loop */ 

fclose(fp); 

return NULL; 
} 

void serve_it(int Client) 
{ 
    void* arg = (void*)Client; 
    pthread_t new_thread; 
    pthread_create(&new_thread, NULL, &client_thread_proc, arg); 
} 

/* Making Server */ 
int main() 
{ 
int sockfd, newsockfd, portno; 
socklen_t clilen; 
char buffer[256]; 
struct sockaddr_in serv_addr, cli_addr; 
int n; 
FILE *fp; 

signal (SIGCHLD, SIG_IGN); 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
    error("ERROR opening socket"); 

bzero((char *) &serv_addr, sizeof(serv_addr)); 

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

if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
     error("ERROR on binding"); 

listen(sockfd,5); 

clilen = sizeof(cli_addr); 

while (1) 
{ 
    printf("Server %d accepting connections\n", getpid()); 

    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 

    serve_it(newsockfd); 
} // serving loop 


close(sockfd); 
return 0; 
} 

...
はどのように作るのですか:

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


#define SOCKET_PORT "50000" 
#define SOCKET_ADR "localhost" 
#define filename "/home/aryan/Desktop/input.txt" 


void error(const char *msg) 
{ 
    perror(msg); 
    exit(0); 
} 


int main() 
{ 
/* Making the client */ 
int sockfd, portno, n; 
struct sockaddr_in serv_addr; 
struct hostent *server; 

char buffer[256]; 

portno = atoi(SOCKET_PORT); 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
    error("ERROR opening socket"); 

server = gethostbyname(SOCKET_ADR); 

if (server == NULL) 
{ 
    fprintf(stderr,"ERROR, no such host\n"); 
    exit(0); 
} 

bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy((char *)server->h_addr, 
    (char *)&serv_addr.sin_addr.s_addr, 
    server->h_length); 
serv_addr.sin_port = htons(portno); 
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
    error("ERROR connecting"); 

/* Time to send the file */ 
FILE *pf; 
unsigned long fsize; 

pf = fopen(filename, "rb"); 
if (pf == NULL) 
{ 
    printf("File not found!\n"); 
    return 1; 
} 
else 
{ 
    printf("Found file %s\n", filename); 

    fseek(pf, 0, SEEK_END); 
    fsize = ftell(pf); 
    rewind(pf); 

    printf("File contains %ld bytes!\n", fsize); 
    printf("Sending the file now"); 
} 

while (1) 
{ 
    // Read data into buffer. We may not have enough to fill up buffer, so we 
    // store how many bytes were actually read in bytes_read. 
    int bytes_read = fread(buffer, sizeof(char),sizeof(buffer), pf); 
    if (bytes_read == 0) // We're done reading from the file 
     break; 

    if (bytes_read < 0) 
    { 
     error("ERROR reading from file"); 
    } 

    // You need a loop for the write, because not all of the data may be written 
    // in one call; write will return how many bytes were written. p keeps 
    // track of where in the buffer we are, while we decrement bytes_read 
    // to keep track of how many bytes are left to write. 
    void *p = buffer; 
    while (bytes_read > 0) 
    { 
     int bytes_written = write(sockfd, buffer, bytes_read); 
     if (bytes_written <= 0) 
     { 
      error("ERROR writing to socket\n"); 
     } 
     bytes_read -= bytes_written; 
     p += bytes_written; 
    } 
}  

printf("Done Sending the File!\n"); 
printf("Now Closing Connection.\n"); 

fclose(pf); 
close(sockfd); 
return 0; 
} 

これはserver.cある

これがいるclient.cですスクリプトは、クライアントからサーバーに受信したファイルに移動しますか?
新しいファイルを同じクライアントに送り返すにはどうすればよいですか?
コードのエラーで私を助けることができたら、私は感謝します。

ありがとうございました。長くお読みいただきありがとうございます。良い一日を!

答えて

5

まずエラー:

#define filename = "Home\\Desktop\\input.txt" 

#define filename "Home\\Desktop\\input.txt" 

する必要がありそうでない場合は、プリプロセッサが

= "Home\Desktop\input.txt" 

ない

"Home\\Desktop\\input.txt" 
を挿入

が必要です。

2番目のエラー:ここ

int bytes_read = read(filename /* THAT IS WRONG, FILE HANDLE MUST BE HERE */, buffer, strlen(buffer) /* also WRONG, must be MAX_BYTES_IN_BUFFER or something */); 

あなたが「PF」から読み取る必要があります(あなたがのfopen()の呼び出しでそれを開いた)、最後の引数は読みたいバイト数でなければなりません。したがって、strlen(バッファ)を実行し、バッファにプログラムの実行時の開始時にいくつかのゴミが含まれているとクラッシュします。strlen()は有効なゼロ終端文字列に対してのみ呼び出される必要があります。配列のサイズではありません!

EDITは:サーバーのループを精緻:

while (1) 
{ 
    printf("Server %d accepting connections\n", getpid()); 

    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 

    serve_it(newsockfd); 
} // serving loop 

serve_itを():あなたはあなたの答えを追加したとき

void serve_int(int Client) 
{ 
    void* arg = (void*)Client; 
    pthread_t new_thread; 
    pthread_create(new_thread, NULL, &client_thread_proc, arg); 
} 

void* client_thread(void* arg) 
{ 
    int thisfd = (int)arg; 
    printf("Server %d: accepted = %d\n", getpid(), thisfd); 

    if (thisfd < 0) 
    { 
     printf("Accept error on server\n"); 
     error("ERROR on accept"); 
     return NULL; 
    } 

    printf("Connection %d accepted\n", thisfd); 

    fp = fopen(filename, "a+b"); 
    if (fp == NULL) 
    { 
     printf("File not found!\n"); 
     return NULL; 
    } 
    else 
    { 
     printf("Found file %s\n", filename); 
    } 

    /* Time to Receive the File */ 
    while (1) 
    { 
     bzero(buffer,256); 
     n = read(thisfd,buffer,255); 
     if (n < 0) error("ERROR reading from socket"); 

     n = fwrite(buffer, sizeof(buffer), 1, fp); 
     if (n < 0) error("ERROR writing in file"); 

     n = write(thisfd,"I am getting your file...",25); 
     if (n < 0) error("ERROR writing to socket"); 
    } /* end child while loop */ 

    return NULL; 
} 
+0

MMMMを、あなたはちょっとserver.cを重複して...あなたはそれをクリアすることができますか?私は守るべきものと守らないことに迷っている...そして私の頭は爆発している。 – AscaL

+0

基本的には、client_thread_procはmain()と関数宣言の2回(2回繰り返されます)(関数が正しく理解されれば、それは大きなifです)。しかし、それが機能であれば、なぜそれを呼び出さないのですか?もしそれがなぜ2回宣言されていないのであれば?私は迷っています:P – AscaL

+0

CはPythonではありません、メイン()からthread_procを削除しました –