2009-10-17 33 views

Trả lời

2

Mã giả:

char newline = '\n'; 
file fd; 
initialize(fd); 
string line; 
char c; 
while(newline != (c = readchar(fd))) { 
line.append(c); 
} 

Something như thế.

+0

Điều này thường đủ tốt, nhưng đôi khi tôi nhận được các dòng dài reaallly, và đọc một char tại một thời điểm quá chậm. –

3

Tôi đang đọc từ ổ cắm TCP mà bạn không thể giả định khi kết thúc dòng. Vì vậy, bạn sẽ cần một cái gì đó như thế:

std::string line; 
char buf[1024]; 
int n = 0; 
while(n = read(fd, buf, 1024)) 
{ 
    const int pos = std::find(buf, buf + n, '\n') 
    if(pos != std::string::npos) 
    { 
     if (pos < 1024-1 && buf[pos + 1] == '\n') 
      break; 
    } 
    line += buf; 
} 

line += buf; 

Giả sử bạn đang sử dụng "\ n \ n" làm dấu phân cách. (Tôi đã không kiểm tra đoạn mã đó ;-))

Trên ổ cắm UDP, đó là một câu chuyện khác. Emiter có thể gửi một paquet chứa toàn bộ một dòng. Người nhận được garanted để nhận paquet như là một đơn vị duy nhất .. Nếu nó nhận được nó, như UDP là không đáng tin cậy như TCP của khóa học.

+0

Đó là về TCP, vâng. Vấn đề là ổ cắm là tương tác. Tôi phải gửi một dòng, sau đó tôi nhận được một vài dòng. Tôi có thể nhận ra kết thúc bằng dòng mới kép "\ n \ n". –

+0

... vì vậy tôi không thể đọc trước 1024 ký tự vì có thể không quá nhiều. người đàn ông 2 đọc cho thấy rằng POSIX đọc có 3 đối số, vì vậy tôi không biết bạn đang đọc cái gì. –

+0

như tôi đã nói với bạn tôi đã không kiểm tra nó. Tôi chỉ viết 'ngay lập tức'. Mã dễ hiểu và thích ứng. Nhân tiện, tôi đã cập nhật nó để tính đến các dấu phân cách dòng của bạn: "\ n \ n" –

0

Sử dụng C++ socket thư viện:

 
class LineSocket : public TcpSocket 
{ 
public: 
    LineSocket(ISocketHandler& h) : TcpSocket(h) { 
    SetLineProtocol(); // enable OnLine callback 
    } 
    void OnLine(const std::string& line) { 
    std::cout << "Received line: " << line << std::endl; 
    // send reply here 
    { 
     Send("Reply\n"); 
    } 
    } 
}; 

Và bằng cách sử dụng lớp trên:

int main() 
{ 
    try 
    { 
    SocketHandler h; 
    LineSocket sock(h); 
    sock.Open("remote.host.com", port); 
    h.Add(&sock); 
    while (h.GetCount()) 
    { 
     h.Select(); 
    } 
    } 
    catch (const Exception& e) 
    { 
    std::cerr << e.ToString() << std::endl; 
    } 
} 

Thư viện chăm sóc của tất cả các xử lý lỗi.

Tìm thư viện sử dụng google hoặc sử dụng liên kết trực tiếp này: http://www.alhem.net/Sockets/

2

Dưới đây là một thử nghiệm, mã khá hiệu quả:

bool ReadLine (int fd, string* line) { 
    // We read-ahead, so we store in static buffer 
    // what we already read, but not yet returned by ReadLine. 
    static string buffer; 

    // Do the real reading from fd until buffer has '\n'. 
    string::iterator pos; 
    while ((pos = find (buffer.begin(), buffer.end(), '\n')) == buffer.end()) { 
    char buf [1025]; 
    int n = read (fd, buf, 1024); 
    if (n == -1) { // handle errors 
     *line = buffer; 
     buffer = ""; 
     return false; 
    } 
    buf [n] = 0; 
    buffer += buf; 
    } 

    // Split the buffer around '\n' found and return first part. 
    *line = string (buffer.begin(), pos); 
    buffer = string (pos + 1, buffer.end()); 
    return true; 
} 

Nó cũng hữu ích để thiết lập tín hiệu SIGPIPE phớt lờ trong việc đọc và viết (và xử lý lỗi như được hiển thị ở trên):

signal (SIGPIPE, SIG_IGN); 
Các vấn đề liên quan