Hilfe bei sockets benoetigt!
-
mein Problem ist einfach der Aufbau der Funktionen. Ich kenne diese Server/Client sockets nur so dass vorher schon alles definiert bzw. initalisiert ist und deshalb kaum Funktionen vorkommen die solche Aufgaben erfüllen, wie z.B.: in den Aufgaben oben. Kannst du mir vielleicht mal einen der beiden Funktionen grob aufstellen, damit ich verstehe was diese Funktion alles erhalten muss.
Ich danke!!!!
-
hiho, also hab ma kurz was geproggt - funktioniert auch, is aber nicht optimal und irgendwie ne mischung aus c und c++ glaub ^^
hier die beiden sources (client und server) - hab versuch die sache noch n bissel zu kommentieren.
client.cpp
#include <iostream> using namespace std; #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define SOCKET_ERROR -1 #define INVALID_SOCKET -1 #define BUFFER_SIZE 4096 bool client_recv(int socket, string *text); int main(int argc, char **argv) { int nSocket = 0; // Socket erstellen nSocket = socket(AF_INET, SOCK_STREAM, 0); // Abfrage ob Socket fehlerhaft if (nSocket == SOCKET_ERROR) { cerr << "Socket konnte nicht erstellt werden" << endl; return 1; } /* Connect-Optionen setzten, sin_addr.s_addr = Adresse auf der "gehört" werden soll sin_port = Port auf dem "gehört" werden soll sin_familie = Zu verwendende Familie (AF_UNIX, AF_INET, ...) */ struct sockaddr_in str_saddy; str_saddy.sin_addr.s_addr = inet_addr("127.0.0.1"); str_saddy.sin_port = htons(6552); str_saddy.sin_family = AF_INET; // Zu einem Rechner verbinden if (connect(nSocket, (sockaddr*)&str_saddy, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { cerr << "Verbindung konnte nicht hergestellt werden" << endl; return 1; } string text; if (client_recv(nSocket, &text)) { cout << "[Nachricht] " << text << endl; } close(nSocket); return 0; } bool client_recv(int socket, string *text) { char caBuffer[BUFFER_SIZE]; int nRecv = 0; nRecv = recv(socket, caBuffer, sizeof(caBuffer) - 1, 0); if (nRecv != INVALID_SOCKET) { caBuffer[BUFFER_SIZE] = '\0'; *text = caBuffer; return true; } return false; }
server.cpp
#include <iostream> #include <string> using namespace std; #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define SOCKET_ERROR -1 #define INVALID_SOCKET -1 int client_send(int socket, string text); int main(int argc, char **argv) { int nSocket = 0; // Socket erstellen nSocket = socket(AF_INET, SOCK_STREAM, 0); // Abfrage ob Socket fehlerhaft if (nSocket == SOCKET_ERROR) { cerr << "Socket konnte nicht erstellt werden" << endl; return 1; } /* Socket Option 'SO_REUSEADDR' setzten, damit der Port bei fehlerhaftem beenden nicht blockiert */ { // Option aktivieren (0 = aus, 1 = ein) int opt = 1; if (setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (char*) &opt, sizeof(opt)) == SOCKET_ERROR) { cout << "Socket hat die Option 'SO_REUSEADDR' nicht erkannt" << endl; } } /* Bind-Optionen setzten, sin_addr.s_addr = Adresse auf der "gehört" werden soll sin_port = Port auf dem "gehört" werden soll sin_familie = Zu verwendende Familie (AF_UNIX, AF_INET, ...) */ struct sockaddr_in str_saddy; str_saddy.sin_addr.s_addr = inet_addr("127.0.0.1"); str_saddy.sin_port = htons(6552); str_saddy.sin_family = AF_INET; // Port an Socket binden if (bind(nSocket, (sockaddr*)&str_saddy, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { cerr << "Socket konnte nicht gebindet werden" << endl; return 1; } // Server in listen-Modus setzten if (listen(nSocket, 3) == SOCKET_ERROR) { cerr << "Socket konnte nicht in 'listen'-Modus geschaltet werden" << endl; return 1; } // Endlose Warteschleife für alle eingehenden Verbindungen do { struct sockaddr_in str_client; socklen_t client_size = sizeof(sockaddr_in); int nClient = accept(nSocket, (sockaddr*)&str_client, &client_size); if (nClient == INVALID_SOCKET) { cerr << "Verbindung zum Client verloren" << endl; } else { string client_ip = inet_ntoa(str_client.sin_addr); cout << "[" << client_ip << "] Verbindung aktzeptiert" << endl; if (client_send(nClient, "hello world") == INVALID_SOCKET) { cerr << "[" << client_ip << "] Nachricht konnte nicht gesendet werden" << endl; } cout << "[" << client_ip << "] Verbindung beendet" << endl; close(nClient); } }while(true); close(nSocket); return 0; } int client_send(int socket, string text) { return send(socket, text.c_str(), text.length(), 0); }
ansonsten nochmal nachfragen!
mfg blan
-
danke erstmal für deine Bemühungen!!!
wenn ich das richtig verstehe, sind dein client und server ein komplettes Programm, was mich wieder etwas verwirrt, da ich ja spezielle Funktionen für so ein Programm erstellen will. Wie stelle ich denn jetzt z.B: die Server Funktion server(int s) auf?
Also ich bekomme s übergeben und soll in einer Endlosschleife jeden Verbindungswunsch annehmen, für Clients aus dem Netz 134.96.0.0 den String "09.09.2005" an den kontaktierenden Host zurücksenden und die Verbindung schließen. Falls der Client nicht aus dem bez. Netz
stammt, soll die Verbindung ohne Antwort geschlossen werden.int accept(int s, struct sockaddr *addr, int *addrlen)
{wenn das netz stimmt, dann
nur einen string(09.09.2005) zurücksenden und dann schließen?
ansonsten
nur schließen?
}welchen rückgabewert brauche ich für die server Funktion und umschließt diese dann die accept Funktion?
brauch wohl hilfe beim code erstellen
hoffe auf weitere Erklärungen
-
hi,
kein problem - eine server-funktion ?
mach in die server-funktion einfach alles server-spezifische rein (bind, listen und accept)
und wenn du eine client-funktion willst machste dort alle client-spez. funktionen rein - das ist hier egtl nur connect.
mfg blan
-
blan schrieb:
hi,
kein problem - eine server-funktion ?
mach in die server-funktion einfach alles server-spezifische rein (bind, listen und accept)
und wenn du eine client-funktion willst machste dort alle client-spez. funktionen rein - das ist hier egtl nur connect.
mfg blan
Also ich blick da noch nicht wirklich durch
bezogen auf die Aufgabe:
bind und listen brauche ich doch dort nicht, oder?Kannst du mir vielleicht mal den strukturellen Aufbau dieser server(int s) Funktion zeigen?
ich stelle mir das im Moment so vor:
int server(int s) {
int accept (int s, struct sockaddr * restrict addr ,
socklen_t * restrict addrlen ) {.....
}}
was brauche ich alles noch und wo kommt diese Endlosschleife hin?
am Beispiel würd ich es, glaube ich am besten verstehen, das gilt auch für die client Funktion.
hoffe sehr auf weitere Erklärungen!!!
danke!!!
-
hi,
also wenn deine funktion int server(int s) client-verbindungen annehmen soll und denen eine nachricht senden soll und zum schluss die verbindung getrennt werden soll sieht die so aus
int server(int nSocket) { do { struct sockaddr_in str_client; socklen_t client_size = sizeof(sockaddr_in); int nClient = accept(nSocket, (sockaddr*)&str_client, &client_size); if (nClient == INVALID_SOCKET) { cerr << "Verbindung zum Client verloren" << endl; } else { string client_ip = inet_ntoa(str_client.sin_addr); cout << "[" << client_ip << "] Verbindung aktzeptiert" << endl; if (client_send(nClient, "hello world") == INVALID_SOCKET) { cerr << "[" << client_ip << "] Nachricht konnte nicht gesendet werden" << endl; } cout << "[" << client_ip << "] Verbindung beendet" << endl; close(nClient); } }while(true); return 0; // keine ahnung wozu du ein return brauchst... }
mfg blan
-
super, danke!!
eine Frage hätt ich dann noch zu dieser Funktion und zwar wegen der Antwort für Clients aus dem Netz 134.96.0.0 . Also dort wo du im code "Verbindung akzeptiert" stehen hast, kommt da das Datum rein? Und wie implementiere ich diese Netzabfrage?
wenn du mir jetzt noch beim client helfen könntest, könnte ich weiter testen und würd dich nicht mehr belästigen
int gettime(struct sockaddr_in *ap, char *buffer)
???struct sockaddr_in str_saddr;
str_saddr.sin_port = htons(13);
str_saddr.sin_family = AF_INET;???
danke nochmal!!!
-
also um das netz abzufragen holst du dir einfach die ip-adresse in dotierter schreibweise und splittest diese nach jedem punk -> dann einfach die einzelteile vergleichen. bei meiner funktion findest du die client ip in der variable client_ip
was willst du bei dem client noch genau wissen?
mfg blan
-
ok danke das mit der Server Funktion hab ich jetzt hoffentlich verstanden.
Beim Client ist mir immer noch der Aufbau schleierhaft, was alles in die Funktion muss und wie das mit dem buffer funktioniert.
-
ehm.. wieso is dir schleierhaft was da rein muss, wie du gesehn hast hab ich auch nur n teil aus der server.cpp in die funktion int server(int nSocket) reingetan.
die recv funktion schreibt die daten die ankommen einfach nur in den buffer den du dann auslesen kannst. versteh net ganz was genau unklar ist.
mfg blan
-
achso "copy and paste"
dann bastel ich mal da jetzt dran rum und geh dann mit rauchendem Kopf ins Bett.
Danke nochmal für die vielen Tipps!!!