Shoutcast senden
-
Die Stichworte sind fnctl mit O_NONBLOCK und select/poll. Skalieren nicht besonders gut aber für wenige Verbindungen eignet sich das ganz hervorragend für nicht-blockierende Socketoperationen ohne Threads.
xstream schrieb:
2. ja sollte, sobald ein fehler besteht also wenn der client off ist ...
Dir ist nicht klar dass strlen herzlich wenig mit dem Client oder Fehlern bei der Übertragung am Hut hat, oder?
EDIT:
Um die letzte Äusserung etwas zu erweitern: Der Rückgabewert von recv ist hier ausschlaggebend, nicht der von strlen, der ist immer > 0 (allein schon weil der Rückgabetyp unsigned ist). Und auch hier sind "Fehler" und "Client hat Verbindung geschlossen" nicht äquivalent, denn wenn recv 0 zurückgibt heisst das, dass der Client die schreibseitige Verbindung geschlossen hat, und wenn recv -1 zurückgibt heisst das, dass ein Fehler (Netzwerk zusammengebrochen, Ressourcen erschöpft, whatsoever) aufgetreten ist.
-
ja das stimmt. tut mir leid, daran hab ich nciht gedacht.
ich werde die beiden stichwörter testen. danke
mfg
xstream
-
guten tag
ich hab nun das fnctl ausprobiert. funktioniert auch, auch das das gesammte passwort nun an den server übermittelt wird, nun meldet aber recv vom shoutcast server, also dort wo das ganze hin soll:
errno: 11
error: Resource temporarily unavailablekann mir darauf noch jemand ne lösung sagen? wäre sehr sehr froh.
mfg
xstream
-
wer gibt diese meldung aus und wo ? (der shoutcast-server ?)
mfg blan
-
mein programm mit der funktion strerror();
die nummer ist in errno nach dem recv() zum shoutcast server.
mfg
xstream
-
ist der rückgabewert von recv überhaupt -1?
-
ja der rückgabe wert ist -1...
-
gib mal den code...
mfg blan
-
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <errno.h> #define BUFFER_SIZE 32 #define LISTENPORT 8016 #define LINEBUFFERING 1 using namespace std; int onair = 0; int Casting (int c) { int sc, scbytes, sendet, recvit; struct sockaddr_in scaddr; socklen_t client_size; sc = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); scaddr.sin_addr.s_addr = inet_addr("85.25.90.52"); scaddr.sin_port = htons(8061); scaddr.sin_family = AF_INET; //setsockopt(sc, SOL_SOCKET, SO_SNDTIMEO, (const char *)10000, 5); //setsockopt(sc, SOL_SOCKET, SO_RCVTIMEO, (const char *)10000, 5); if (connect(sc, (struct sockaddr*)&scaddr, sizeof(scaddr)) == -1) { cout << "Cannot connect to Shoutcast! " << errno; } else { char sc_buffer[1024], c_buffer[1024]; fcntl(sc, F_SETFL, O_NONBLOCK); int answer_c, answer_sc; while (true) { cout << "Datas:\n------\n"; answer_c = recv(c, sc_buffer, strlen(sc_buffer), 0); sc_buffer[answer_c] = '\0'; send(sc, sc_buffer, strlen(sc_buffer), 0); answer_sc = recv(sc, c_buffer, strlen(c_buffer), 0); c_buffer[answer_sc] = '\0'; send(c, c_buffer, strlen(c_buffer), 0); cout << answer_c << " .. " << answer_sc << ".."; cout << strerror(errno) << "Length of buffer from Client: " << strlen(sc_buffer) << "; Value: " << sc_buffer << "(" << answer_c << ")" << "\nLength of buffer from Server: " << strlen(c_buffer) << "; Value: " << c_buffer << "(" << answer_sc << ")" << "\n\n"; if (answer_c < 0 || answer_sc < 0) { break; } sc_buffer[0] = 0; c_buffer[0] = 0; } } cout << "Loose Connection!\n"; close(c); close(sc); //system("cd /root/playlist; ./sc_trans &"); cout << "Started sc_trans\n"; onair = 0; return 0; } int main() { int s, c, scbytes; struct sockaddr_in sockAddr1, client; socklen_t client_size; s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); //fcntl(s, F_SETFL, O_NONBLOCK); if (s < 0) { cout << "No Socket\n"; } else { cout << "Listening to Port ... Please wait!\n"; sockAddr1.sin_family = AF_INET; sockAddr1.sin_port = htons(LISTENPORT); sockAddr1.sin_addr.s_addr = INADDR_ANY; if (bind(s, (struct sockaddr*)&sockAddr1, sizeof(sockAddr1)) == -1) { cout << "Error binding\n"; } else { if (listen(s, 5) == -1) { cout << "Cannot Listening\n"; } else { for (;;) { client_size = sizeof(client); c = accept(s, (struct sockaddr*)&client, &client_size); if (c == -1) { cout << "Cannot Accept\n"; } else { cout << "Accpeted: " << inet_ntoa(client.sin_addr) << ":" << ntohs(client.sin_port) << "\n"; if (onair == 1) { send(c, "Leider ist der Stream bereits besetzt.", 38, 0); cout << "Sorry Message sendet\n"; } if (onair == 0) { onair = 1; //system("killall -KILL sc_trans "); cout << "Killed sc_trans\n\n"; Casting(c); onair = 0; } } } close(c); } } } close(s); }
-
das kommt daher weil du den socket in den non-blocking modus gesetzt hast.
-
das ist ja soweit ich das verstanden hab das ziel, so das man weiterarbeiten kann...
-
so wie du das programmiert hast ist das aber sinnfrei! du musst noch select, poll, epoll oder etwas ähnliches einbauen.
-
Richtig. Non-Blocking heisst ja eben dass recv nicht wartet bis ein komplettes Paket angekommen ist. Folglich signalisiert er Dir "es sind gerade keine Daten zu empfangen". Mit select/poll/epoll kannst Du dann mehrere Sockets gleichzeitig darauf testen ob Daten zu empfangen sind und bei denen das der Fall ist diese verarbeiten...
-
naja ... ich bin vieleicht ein idiot...
aber kurz gesagt. es funktioniert. ich muss das ganze noch verbessern bezüglich listen-port eingabe usw aber das komtm gut. also die hauptfunktion das was ich von euch wissen woltle funktioniert jetzt ohne irgend ein problem.
ihr habt mir die augen geöffnet... auf http://www.pc-adviser.de/socket_programmierung.html findet sich ein script welches genau diese problem mit select anspricht. nun auf der seite hatte ich mir die meisten informationen bezüglich listen und send und recv usw geholt, hab mir das script selber auch mehrere male angeschaut, aber das ich das brauchen könnte kam mir nie in den sinn... das prgramm wird bald von meiner homepage download bar sein, solltet ihr auch mal ein internet radio machen^^...
vielen vielen dank und freundliche grüsse
xstream
-
guten tag
das programm funktionierte in den test läufen mit meinem pc ohne weiteres... als es nun aber auf unseren servers installiert wurde, will es nicht mehr... das programm stürtzt je nach lust und laune einfach ab und der moderator hatte seine sendung....
unter der angegebenen adresse findet ihr den quellcode. kann jemand mögliche fehler entdecken, die zu einem absturtz führen könnten?
findet jemand möglichkeiten, das programm stabiler zu gestallten, so das abstürtzde weniger oft passieren können?
gibt es eine möglichkeit, wenn das programm abstürtzt, den port von der qual des geschrotteten programmes zu befreien?
ich danke für die hilfe
mfg
xstream
-
also ich seh keine url
ja, man kann mit den socket-optionen festlegen dass der port nicht "blockiert" - schau dir mal die API an - finds grad nicht...
mfg blan
-
-
kleiner tipp: veruchs doch mal mit der libshout - ich bin selber grad an einer software dran die den icecast server mit audio-daten versorgt und damit funktionerts wunderbar.
mfg blan
-
was kann ich mit der libshout dann anfangen?
gibts da zb ein tutorial dazu oder sonst irgendwo eine hilfe?
mfg
xstream
-
lad se dir doch einfach mal runter, da sollte ein ordner sein der sich "example" nennt.
mfg blan