2013-01-06 15 views
7

tôi cần phải gửi dữ liệu qua sử dụng socket, về cơ bản chuyển một tập tin,Hàm send() trong C cách xử lý nếu không phải tất cả các byte đều được gửi?

Theo send() chức năng docs, nó nói,

If no error occurs, send returns the total number of bytes sent, which can be less than the number requested to be sent in the len parameter. Otherwise, a value of SOCKET_ERROR is returned, 

Điểm mấu rằng tôi lo lắng về việc là, sự trở lại giá trị có thể nhỏ hơn giá trị được yêu cầu. Bởi vì tôi đang đọc từ một tập tin và ghi vào một ổ cắm, bởi vì nó có thể không gửi tất cả các byte, tôi đoán tôi sẽ phải thử lại nếu bộ đệm đầy đủ không được gửi? trong trường hợp đó tôi đoán tôi sẽ phải bằng cách nào đó trước con trỏ trên cùng một bộ đệm bằng byte đọc và gửi nó một lần nữa ??

Tôi chỉ muốn biết nếu đó là cách về nó? hoặc là có một cách thông minh nhiều đến nó, để tất cả các dữ liệu được yêu cầu được gửi mà không cần phải lo lắng về thời điểm không phải tất cả dữ liệu được gửi đi?

Cảm ơn,

+1

Cả hai quá trình gửi và nhận nên xử lý các trường hợp khi dữ liệu đã được chia trong khối bằng việc triển khai giao thức TCP/IP. Vì vậy, bạn có thể cần phải làm một số 'gửi' và' recv' và bạn nên quan tâm đến kết quả. –

+1

Bạn sẽ thấy rằng tình trạng này không bao giờ thực sự phát sinh trong chế độ chặn, bất kể tài liệu nói gì. 'send()' chặn cho đến khi tất cả dữ liệu đã được chuyển vào bộ đệm gửi socket. – EJP

+0

@EJP Nó _can_ phát sinh trong chế độ chặn mặc dù. Ví dụ, nếu một trình xử lý tín hiệu ngắt một 'send()' đã truyền một số dữ liệu, nhưng không phải tất cả. – mtk

Trả lời

10

Có, bạn phải nâng cấp con trỏ đệm và lặp lại cuộc gọi send cho đến khi toàn bộ bộ đệm được tiêu thụ hoặc bạn gặp lỗi nghiêm trọng. Các thành ngữ tiêu chuẩn trông giống như sau:

int 
send_all(int socket, const void *buffer, size_t length, int flags) 
{ 
    ssize_t n; 
    const char *p = buffer; 
    while (length > 0) 
    { 
     n = send(socket, p, length, flags); 
     if (n <= 0) 
      return -1; 
     p += n; 
     length -= n; 
    } 
    return 0; 
} 

Lưu ý rằng nếu bạn đang gửi datagram có ranh giới quan trọng (ví dụ UDP), bạn không thể sử dụng kỹ thuật này; bạn phải đối xử với một gửi ngắn như là một thất bại.

3

Vâng, bạn phải lo lắng về giá trị trả về bởi send (hoặc write và vân vân). Không có cách nào cực kỳ thông minh xung quanh nó, nhưng có một vài chức năng được viết bởi Richard Stevens tuyệt vời, cụ thể là readnwriten.

This article on informit dường như có phiên bản của các chức năng này.

6

Bạn có thể thử một cái gì đó như:

int ret, bytes = 0; 
while (bytes < buflen) { 
    ret = send(sock_fd, buf+bytes, buflen-bytes, flags); 
    //check for errors 
    if (ret == -1) { 
     // handle error 
    } 
    bytes+=ret; 
} 
Các vấn đề liên quan