c recv() liest bis zum newline-Auftritt
Dem ich arbeite, schreiben einen IRC-bot in C, und lief in einen Haken.
In meiner main-Funktion Erzeuge ich meine Buchse und verbinden alle, die gerne Sachen. Dann habe ich eine (fast) unendliche Schleife zu Lesen, was gesendet wird wieder vom server. Ich gebe dann was Lesen Sie aus, um eine Hilfsfunktion, processLine(char *line)
- das problem ist, dass der folgende code liest, bis mein Puffer voll ist - ich will es nur text Lesen, bis ein newline (\n) oder carriage return (\r) Auftritt (also Ende der Zeile),
while (buffer[0] && buffer[1]) {
for (i=0;i<BUFSIZE;i++) buffer[i]='\0';
if (recv(sock, buffer, BUFSIZE, 0) == SOCKET_ERROR)
processError();
processLine(buffer);
}
Was am Ende passiert, ist, dass viele Linien eingeklemmt werden alle zusammen, und ich kann nicht verarbeiten, die Zeilen richtig, wenn das passiert.
Wenn Sie nicht vertraut mit IRC-Protokollen, eine kurze Zusammenfassung wäre, dass, wenn eine Nachricht gesendet wird, ist es oft sieht wie folgt aus: :YourNickName!YourIdent@YourHostName PRIVMSG #someChannel :The rest on from here is the message sent...
und ein login-beachten Sie, zum Beispiel, ist so etwas wie dieses: :the.hostname.of.the.server ### bla some text bla
mit ### als code(?) verwendet für die Verarbeitung - D. H. 372 ist ein Indikator, dass der folgende text ist Teil der Nachricht Des Tages.
Wenn es alle zusammengestaucht, ich kann nicht Lesen, was Zahl ist, für welche Linie kann ich da nicht finden, wo Sie eine Linie beginnt oder endet!
Ich würde schätzen, Hilfe bei diesem sehr viel!
P. S.: Dieser wird kompiliert/lief auf linux, aber ich will schließlich die Portierung auf windows, so bin ich so viel davon wie ich kann multi-Plattform.
P. S. S.: Hier ist meine processLine () - code:
void processLine(const char *line) {
char *buffer, *words[MAX_WORDS], *aPtr;
char response[100];
int count = 0, i;
buffer = strdup(line);
printf("BLA %s", line);
while((aPtr = strsep(&buffer, " ")) && count < MAX_WORDS)
words[count++] = aPtr;
printf("DEBUG %s\n", words[1]);
if (strcmp(words[0], "PING") == 0) {
strcpy(response, "PONG ");
strcat(response, words[1]);
sendLine(NULL, response); /* This is a custom function, basically it's a send ALL function */
} else if (strcmp(words[1], "376") == 0) { /* We got logged in, send login responses (i.e. channel joins) */
sendLine(NULL, "JOIN #cbot");
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den üblichen Weg, um sich mit diesem zu
recv
in eine persistente Puffer in Ihrer Anwendung, dann ziehen Sie eine einzelne Zeile aus, und verarbeiten Sie. Später können Sie die verbleibenden Zeilen in den Puffer vor dem Aufrufrecv
wieder. Beachten Sie, dass die Letzte Zeile in den Puffer nur teilweise erhalten; Sie müssen sich dieser Fall durch eine erneute Eingaberecv
um die Linie abzuschließen.Hier ist ein Beispiel (völlig ungetestet! sieht auch für einen
\n
, nicht\r\n
):(inbuf - line_start);
sollte(line_start - inbuf);
TCP
bietet keine Sequenzierung der Art. Wie @bdonlan schon sagte, Sie implementieren sollten, so etwas wie:recv
aus der Steckdose in einen Pufferrecv
prüfen, ob die empfangenen bytes enthalten eine\n
\n
verwenden Sie alles, was Sie bis zu diesem Punkt aus dem Puffer (und klar, es)Habe ich nicht ein gutes Gefühl (ich habe irgendwo gelesen, man soll nicht mischen, low-level-I/O mit
stdio
I/O), aber Sie können möglicherweise verwenden Siefdopen
.Alles, was Sie tun müssen, würde ist
fdopen(3)
verknüpft Ihre Buchse mit einemFILE *
setvbuf
zu sagen, stdio, dass Sie wollen, dass es line-buffered - (_IOLBF
) im Gegensatz zu den Standard-block-gepuffert.Zu diesem Zeitpunkt sollten Sie haben effektiv bewegt sich die Arbeit aus den Händen zu
stdio
. Dann könnte man über die Verwendungfgets
auf derFILE *
._fdopen
. Über dieerrno
Teil, bei der Verwendung vonstdio
Fehler prüfen mitferror
,feof
. Offensichtlich stellt dies weniger details als einerecv
oder eineread
tut. Der standard sagt, keine Funktion sollteerrno
auf 0, aber ich glaube, es bedeutet "Erfolg". Also selbst wenn einrecv
fehl, kann der tatsächliche fgets gelingt.