簡體   English   中英

從套接字讀取C語言的數據直到結束字符

[英]Reading Data in C From Socket Until End Character

編輯:在評論中已經證明定義長度應該產生相同的結果,並且不會使用任何重要的額外數據。 如果您正在尋找一種在運行程序的計算機之間發送數據的方法,則發送長度比讀取直到終止字符要好。 BonzaiThePenguin有一些非常好的方面您應該注意。

但是出於教育目的:我從來沒有找到好的示例代碼來為標准C套接字執行此操作,該標准C套接字處理的情況是,一個包中未全部接收數據,或者一個包中包含多個單獨的消息。 簡單地反復調用recv並非在所有情況下都可行。

這是我自己在下面回答的問題之一,但是我對自己的回答沒有100%的信心。

“允許客戶端指定要發送的消息的大小不是危險的”。 這個詞中的大多數協議都可以做到這一點,包括HTTP和SSL。 僅當實現未正確對消息進行邊界檢查時,這才是危險的。

建議的致命缺陷是它不適用於二進制數據:您必須引入轉義符,以便終止符可以出現在消息中,然后當然也需要轉義。 所有這些都在兩端增加了處理和數據復制。

這是我想出的。 我不能保證這是完美的,因為我不是專業人士,所以如果有任何錯誤,如果有人指出,我(以及其他尋求幫助的人)將不勝感激。

上下文:socket是套接字,buffer是存儲所有網絡輸入的數組,line是僅存儲從緩沖區提取的一條消息的數組(這是程序的其余部分使用的),length是兩個輸入數組的長度,和recvLength是指向存儲在函數外部的整數的指針,該整數最初應為0,並且不應由其他任何東西釋放或修改。 也就是說,它應該在同一套接字上的多次調用中保持不變。 此函數返回在行數組中輸出的數據的長度。

size_t recv_line(int socket, char* buffer, char* line, size_t length, size_t* recvLength){ //receives until '\4' (EOT character) or '\0' (null character)

size_t readHead = 0;
size_t lineIndex = 0;
char currentChar = 0;
while (1){
    for (; readHead < *recvLength; readHead = readHead + 1){
        currentChar = buffer[readHead];
        if (currentChar=='\4' || currentChar=='\0'){ //replace with the end character(s) of your choice
            if (DEBUG) printf("Received message===\n%s\n===of length %ld\n", line, lineIndex+1);
            memcpy(buffer, buffer + readHead + 1, length-(readHead)); //shift the buffer down
            *recvLength -= (readHead + 1); //without the +1, I had an "off by 1" error before!
            return lineIndex+1; //success
        }
        if (readHead >= length){
            if (DEBUG) printf("Client tried to overflow the input buffer. Disconnecting client.\n");
            *recvLength = 0;
            return 0;
        }
        line[lineIndex] = currentChar;
        lineIndex++;
    }
    *recvLength = recv(socket, buffer + readHead, length, 0);
}
printf("Unknown error in recv_line!\n");
return 0;

}

簡單示例用法:

int function_listening_to_network_input(int socket){
char netBuffer[2048];
char lineBuffer[2048];
size_t recvLength = 0;

while (1==1){
size_t length = recv_line(socket, netBuffer, lineBuffer, 2048, &recvLength);
// handle it…
}
return 0;
}

請注意,這並不總是將行保留為以空值結尾的字符串。 如果您願意,可以輕松進行修改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM