TCP-Verbindung C -> VB.Net
-
Hi,
Ich habe einen TCP-Server mit C geschrieben. Der läuft auf einem Debian-System.
Als Client habe ich ein VB.Net-Programm.Ich kann mit dem Client zum Server connecten und auch Daten senden.
Jedoch kann ich die Daten die vom Server kommen nicht auslesen.Hier die Codes:
Server: (C)
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <strings.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> #include <errno.h> #define ZEILENLAENGE 10 pthread_t thread_counter_get, thread_counter_set; char *ptr, *ptr_counter_get, ptr_counter_set; char buffer[20], buffer_temp[20], puffer[ZEILENLAENGE]; char *ar_counter_set[1]; int x, iMinuten, connected = 0, csd; FILE *quelle; void *func_counter_get (void* p) { // Der Type ist wichtig: void* als Parameter und Rückgabe if( (quelle=fopen("counter.txt","r")) == NULL) { // Versuchen Datei zu öffnen fprintf(stderr, "Kann Datei nicht oeffnen\n"); // Lesen Fehlerhaft return EXIT_FAILURE; } // Lesen Fehlerfrei fgets(puffer, ZEILENLAENGE, quelle); fclose(quelle); iMinuten=puffer; printf("counter=%s\n",iMinuten); /*return EXIT_SUCCESS; */ //return NULL; // oder in C++: return 0;// Damit kann man Werte zurückgeben } void *func_counter_set (void* p) { // Der Type ist wichtig: void* als Parameter und Rückgabe printf("test1234\n"); /* x = 0; ptr_counter_set = strtok(buffer_temp, ";"); // buffer_temp bei ; trennen und in ptr schreiben while(ptr_counter_set != NULL) { ar_counter_set[x]=ptr_counter_set; //printf("Hier: %s\n",ueberschuss_counter_get[x]); x++; ptr_counter_set = strtok(NULL, ";"); // naechsten Abschnitt erstellen } return NULL; // oder in C++: return 0;// Damit kann man Werte zurückgeben */ } void Eth_Send_Recv_Data() { //printf("punkt1\n"); while(connected) { // Vom Client lesen und ausgeben memset(buffer, 0, sizeof(buffer)); int bytes = recv(csd, buffer, sizeof(buffer), 0); if (bytes == 0 || bytes == -1 ){ //csd=0; connected=0; printf("Client getrennt!\n"); } else { //printf("Der Client hat folgenden String gesendet: %s\n", buffer); //printf("Es wurden %d Bytes empfangen\n", bytes); //Empfangene Daten verarbeiten sprintf(buffer_temp,"%s",buffer); ptr = strtok(buffer, ";"); // string bei ; trennen und in ptr schreiben //if (strcmp(ptr, "counter_get") != 0) { if (strstr(ptr, "counter_get") !=NULL ) { //printf("getcounter\n"); pthread_create(&thread_counter_get, NULL, func_counter_get, NULL); // Thread aufrufen pthread_join (thread_counter_get, NULL); // Auf Threadende warten //printf("getcounter2\n-------------------\n"); } else if (strstr(ptr, "counter_set") !=NULL ) { //printf("setcounter1\n"); pthread_create(&thread_counter_set, NULL, func_counter_set, NULL); pthread_join (thread_counter_set, NULL); //printf("setcounter2\n-------------------\n"); } else { //printf("andere\n"); } } } } int main(void) { /* Server-Anfang */ /* Socket erstellen - TCP, IPv4, keine Optionen */ int lsd = socket(AF_INET, SOCK_STREAM, 0); /* IPv4, Port: 50125, jede IP-Adresse akzeptieren */ struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(50125); saddr.sin_addr.s_addr = htons(INADDR_ANY); /* Socket an Port binden */ bind(lsd, (struct sockaddr*) &saddr, sizeof(saddr)); /* Auf Socket horchen (Listen) */ listen(lsd, 20); /* Puffer und Strukturen anlegen */ struct sockaddr_in clientaddr; bzero(buffer, sizeof(buffer)); while(1) { /* Auf Verbindung warten, bei Verbindung Connected-Socket erstellen */ socklen_t clen = sizeof(clientaddr); csd = accept(lsd, (struct sockaddr*) &clientaddr, &clen); if (csd == -1) { perror("Fehler bei accept()\n" ); printf("Errno Code:\t%d\n",errno); } else { connected=1; printf("Client verbunden!\n"); Eth_Send_Recv_Data(); } } }
Client: (VB.Net)
Private Sub Connect(ByVal server As String, ByVal message As String) Try ' Create a TcpClient. ' Note, for this client to work you need to have a TcpServer ' connected to the same address as specified by the server, port ' combination. Dim port As Int32 = 50125 Dim client As New TcpClient(server, port) ' Translate the passed message into ASCII and store it as a Byte array. Dim data As Byte() = System.Text.Encoding.ASCII.GetBytes(message) ' Get a client stream for reading and writing. ' Stream stream = client.GetStream(); Dim stream As NetworkStream = client.GetStream() ' Send the message to the connected TcpServer. stream.Write(data, 0, data.Length) Console.WriteLine("Sent: {0}", message) ' Receive the TcpServer.response. ' Buffer to store the response bytes. data = New Byte(256) {} ' String to store the response ASCII representation. Dim responseData As String = String.Empty ' Read the first batch of the TcpServer response bytes. Dim bytes As Int32 = stream.Read(data, 0, data.Length) responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes) Console.WriteLine("Received: {0}", responseData) ' Close everything. stream.Close() client.Close() Catch e As ArgumentNullException Console.WriteLine("ArgumentNullException: {0}", e) Catch e As SocketException Console.WriteLine("SocketException: {0}", e) End Try Console.WriteLine(ControlChars.Cr + " Press Enter to continue...") Console.Read() End Sub 'Connect
Nachdem ich connected habe, sende ich z.B. ein counter_get an den Server. Dieser verarbeitet das und gibt den Inhalt einer Datei aus.
Soweit in Ordnung. Der Client läuft, bis zu Zeile 29:Dim bytes As Int32 = stream.Read(data, 0, data.Length)
Hier hängt sich das Programm dann auf, bis der Server wieder geschlossen wird.
Hat von euch jemand eine Ahnung, woran das liegen kann?
Sendet der Server die Daten falsch raus? Fehlt beim Client noch was?Viele Danke für die Hilfe...
-
Hallo,
Vielleicht bin ich ja zu blöd es zu sehen, aber ich finde keine einzige Zeile in Deinem Server wo er auch nur 1 Byte sendet.
mfg Martin
-
mgaeckler schrieb:
Hallo,
Vielleicht bin ich ja zu blöd es zu sehen, aber ich finde keine einzige Zeile in Deinem Server wo er auch nur 1 Byte sendet.
mfg Martin
so ziemlich die letzte Zeile im geposteten Code lautet
Eth_Send_Recv_Data();
Da wirds doch irgendeinen Weg geben, den Erfolg des Ganzen im Server zu protokollieren, oder?
-
h0rst schrieb:
so ziemlich die letzte Zeile im geposteten Code lautet
Eth_Send_Recv_Data();
Da wirds doch irgendeinen Weg geben, den Erfolg des Ganzen im Server zu protokollieren, oder?
Namen sind Schall und Rauch. Wo siehst Du bei der Definition der Funktion Eth_Send_Recv_Data irgendeinen Aufruf einer Sendefunktion?
mfg Martin
-
Ich hatte darauf gehofft, dass der TE seine Funktion nochmal ansieht und sich dann womöglich selbst fragt, wie er den Erfolg von nichts protokollieren kann
-
h0rst schrieb:
Ich hatte darauf gehofft, dass der TE seine Funktion nochmal ansieht und sich dann womöglich selbst fragt, wie er den Erfolg von nichts protokollieren kann
Naja, der TE ist mit der C Programmierung scheinbar eh überfordert. Da sind so viele Fehler drinnen, daß es sich nicht lohnt, weiter darüber zu schauen.
mfg Martin
-
Danke, sehr nett...
Wo siehst Du bei der Definition der Funktion Eth_Send_Recv_Data irgendeinen Aufruf einer Sendefunktion?
Das war ja auch eine meiner Fragen. Sendet der Server die Daten falsch raus...
Ich dachte, die printf-Anweisung ist das, was der Server rausgibt.
Wie kann ich das als Neuling in C nur verwechseln... Tut mir schrecklich leid...
-
T1g0r schrieb:
Danke, sehr nett...
Wo siehst Du bei der Definition der Funktion Eth_Send_Recv_Data irgendeinen Aufruf einer Sendefunktion?
Das war ja auch eine meiner Fragen. Sendet der Server die Daten falsch raus...
Ich dachte, die printf-Anweisung ist das, was der Server rausgibt.
Wie kann ich das als Neuling in C nur verwechseln... Tut mir schrecklich leid...In nahezu jeder Dokumentation zu printf steht, daß es seine Ausgabe zum Standardausgabekanal schickt. Das ist für gewöhnlich die Konsole. Es nützt Dir auch nix zu denken, das sei jetzt Dein socket stream, Du mußt es Deinem System auch sagen. Computer können immer noch nicht Gedanken lesen.
Darüber hinaus solltest Du Dich mit den Grundlagen der C-Programmierung beschäftigen bevor Du anfängst einen Server zu schreiben. Dann müssen wir auch nicht mehr so einen Unfug wie in den Zeilen 30 und 31 lesen. Gerade wenn man nichts weiß, sollte man die Warnungen des Compilers weder abschalten noch ignorieren.
mfg Martin
Edit: Das Zauberwort zum Umleiten der Standardausgabe heißt übrigens dup2.