2012-06-27 33 views
5

Đầu tiên và trên hết, cảm ơn tất cả các bạn đã đọc và giúp đỡ, tôi rất biết ơn.
Thứ hai Tôi xin lỗi nhưng tôi vẫn còn mới vào trang web này và tiếng Anh không phải là ngôn ngữ mẹ đẻ của tôi vì vậy tôi có thể làm một số lỗi định dạng và ngôn ngữ. Tôi xin lỗi trước.
Ngoài ra, kiến ​​thức C của tôi không tốt, nhưng tôi sẵn sàng học hỏi và cải thiện.
Bây giờ, với vấn đề trong tầm tay:Gửi và nhận tệp (Máy chủ/Khách hàng) trong C bằng cách sử dụng ổ cắm trên Unix

Điều tôi cần làm là tạo Máy khách và Máy chủ, đồng thời yêu cầu máy chủ lắng nghe các kết nối đến.
Sau đó, tôi có Khách hàng gửi một tệp văn bản khá lớn (tôi biết nó sẽ chỉ là MỘT tệp) cho Máy chủ.
Máy chủ sau đó sẽ thực hiện một số thao tác trên tệp (nó sẽ chạy một tập lệnh trên tệp được gửi để tạo ra một tệp khác ở đầu ra có tên là "output.txt"). Máy chủ sau đó sẽ cần phải gửi tệp output.txt trở lại Máy khách.

Bây giờ, tôi đã biết cách tạo một Máy khách và Máy chủ (tôi đọc hướng dẫn beej và một số nội dung khác trên trang này), thậm chí tho tôi có thể đã phạm một số sai lầm. Tôi cần một số trợ giúp với máy chủ lưu trữ tệp, sau đó gọi tập lệnh và gửi tệp khác lại cho máy khách. Hiện tại, những gì tôi đã làm là Máy chủ và Máy khách ... Tôi không thực sự biết cách tiếp tục.
Trên một lưu ý phụ, tôi đã tạo các tệp này bằng cách sử dụng những gì tôi tìm thấy trên trang web này và trên internet, tôi hy vọng chúng không quá lộn xộn, vì tôi không giỏi về lập trình viên.

Đây là client.c

#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; 
} 

Đây là server.c:

#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; 
} 

tôi muốn một số gợi ý về cách đi trên ...
Làm thế nào để làm cho một kịch bản đi trên tập tin tôi nhận được từ máy khách đến máy chủ?
Làm cách nào để gửi lại tệp mới cho cùng một ứng dụng?
Và nếu bạn có thể giúp tôi với các lỗi trong mã tôi muốn biết ơn.

Cảm ơn tất cả và xin lỗi vì đã đọc lâu. Chúc một ngày tốt lành!

Trả lời

5

lỗi đầu tiên:

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

nên

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

Nếu không, tiền xử lý chèn

= "Home\Desktop\input.txt" 
không

các

"Home\\Desktop\\input.txt" 

mà bạn mong đợi.

lỗi thứ hai:

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 */); 

Ở đây bạn phải đọc từ "pf" (bạn đã mở nó với fopen() gọi) và đối số cuối cùng phải là số byte bạn muốn đọc. Vì vậy, nếu bạn làm strlen (buffer) và bộ đệm chứa một số rác ở đầu thời gian chạy của chương trình, bạn sẽ nhận được một vụ tai nạn.strlen() chỉ phải được gọi cho chuỗi không bị chấm dứt hợp lệ, nó không phải là kích thước của mảng!

EDIT: xây dựng vòng lặp của máy chủ:

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

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

    serve_it(newsockfd); 
} // serving loop 

Các 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 khi bạn thêm câu trả lời của bạn, bạn kinda nhân đôi server.c ... bạn có thể rõ ràng nó lên? Tôi đang bị mất về những gì để giữ và những gì không giữ ... và đầu của tôi là phát nổ. – AscaL

+0

về cơ bản điều là client_thread_proc được lặp lại hai lần, một trong chính() và một như khai báo hàm (nếu bạn hiểu nó một cách chính xác, và đó là một lớn nếu). nhưng nếu nó là một funcion tại sao không chỉ gọi nó? và nếu nó không phải là lý do tại sao khai báo nó 2 lần? Tôi đang bị lạc: P – AscaL

+0

C không phải là python, tôi đã gỡ bỏ thread_proc từ chính() –

Các vấn đề liên quan