2012-04-08 7 views
2

ich ein Java-Socket-Server und c Socket-Client, hier sind der Codesenden und recv auf Sockel

Java-Socket-Server:

int Send_Request(String s) { 

    try { 
     os = socket.getOutputStream(); 
     os.write(s.getBytes()); 
     os.flush(); 

     Log.d(tag,"Data = " + s); 

     return 0; 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     Log.e(tag,"Send Request Error"); 
     return -1; 
    } 

C Socket-Client:

void* recv_request() 
{ 
int i,in; 
char buf[1024]; 
while(1) 
{ 
    if ((in = read(sockfd, buf, strlen(buf))) != -1) 
    { 
     LOGD("Received = %s ...",buf); 
     sendServerCutText(buf); 
     memset(buf,0,strlen(buf)); 
    } 

} 

}

Das Problem ist .. wenn ich vom Server senden, blockiert es auf Flush(), kann der Client c nicht empfangen bis Es wird ein weiterer Send_Request aufgerufen.

wo ist das Problem ??

+0

Warum spülen Sie? –

+3

Sie können 'strlen (buf)' nur aufrufen, wenn 'buf' eine Zeichenfolge im C-Stil enthält. Sie erhalten beliebige Binärdaten, keine C-Style-Strings. Und du nennst sogar "strlen", bevor du irgendwelche Daten hast! –

Antwort

3

Es gibt ein konzeptionelles Problem. Sie denken, TCP ist nachrichtenorientiert (Nachrichten mit der angegebenen Länge senden). Es ist nicht so, es stellt nur einen Strom von Bytes zur Verfügung.

Zum Senden einer Nachricht mit einer bestimmten Länge ist es üblich, zunächst die Länge (codiert in fester Länge, z. B. 4 Byte Integer in Netzwerk-Byte-Reihenfolge) und dann die eigentliche Nachricht zu senden.

Es gibt auch ein Implementierungsproblem, das 3. Argument für das Lesen sollte die maximale Leselänge sein, die 1024 sein sollte, Ausführen strlen auf einem nicht initialisierten lokalen Char-Array ist eindeutig undefiniert-Verhalten.

+1

Wenn die Länge vor dem Senden nicht bekannt ist oder das Nachrichtenformat textuell sein muss, ist es auch möglich, eine spezielle Byte- oder Zeichenfolge als Trennzeichen zwischen Nachrichten zu senden. Bei Protokollen wie Telnet ist der Zeilenumbruch ein natürlicher Nachrichtentrenner. –

+0

und HTTP verwendet String-Darstellung der Länge. –

+0

ist es richtig für mich, os.write (s.length()) hinzuzufügen; vor os.write (s.getBytes()), und dann zuerst lesen (sockfd, buflen, 4), dann wieder mit lesen lesen (sockfd, buf, ???)? –