PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : integer über sockets übertragen



moedule
29-04-2005, 14:16
hey

ich hab noch nicht viel mit socket programmierung in c/c++ gemacht und wollte das ganze jetzt mal etwas intensivieren

nach etwas suche hab ich dann auch mal eine implemntierung in c++ gefunden, also richtig mit ner socketklasse, ... und eben nicht nur die reine c variante

damit ist es mir möglich strings zu übertragen. damit kann man zwar schon nette sachen machen (webserver ... ) aber für meine zwecke wäre es ganz nett integer zahlen (oder auch double) zu übertragen, um diese nicht über einen string übertragen zu müssen (uneffektiv, aufwendig , ....)

ist sowas eigentlich möglich? denn alle funktionen die ich benutze wollen strings / bzw char arrays

wenn sowas nicht einfach möglich ist, wie übertragt man integer dann am besten?

(das es möglich ist, sehe ich an implemtierungen für CPPvm (implemntierung für paralles rechnen), da kann man gnaze objekte austauschen, also wohl auch integer, aber ist halt doch etwas aufwendig

moe

diese socket klasse hab ich im netz gefunden und einfach mal etwas damit rumgespielt


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>


class Socket
{
public:
Socket();
virtual ~Socket();

// Server initialization
bool create();
bool bind ( const int port );
bool listen() const;
bool accept ( Socket& ) const;

// Client initialization
bool connect ( const std::string host, const int port );

// Data Transimission
bool send ( const std::string ) const;
int recv ( std::string& ) const;

void set_non_blocking ( const bool );
bool is_valid() const { return m_sock != -1; }

private:

int m_sock;
sockaddr_in m_addr;
};


und hier noch z.B. die implementierung der send-function


bool Socket::send ( const std::string s ) const
{
int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
if ( status == -1 )
{
return false;
}
else
{
return true;
}
}

Joghurt
29-04-2005, 14:54
bool Socket::send(const int i) const {
int status = ::send ( m_sock, &i, sizeof(int), MSG_NOSIGNAL );
...Sockets kannst du genauso wie non-seekable Dateien behandeln.

moedule
29-04-2005, 15:13
hey

auja das ging recht einfach, senden müßte jetzt gehen, für den empfang werd ich mich mal hinsetzen müssen, denn da blick ichs nicht ganz

hier mal die empfangen funktion, erst für strings (die tut), dann für int (die tut nicht)

krieg da halt folgende meldung beim compilieren
Socket.cpp:166: error: invalid conversion from `int' to `void*'




int Socket::recv ( std::string& s ) const
{
char buf [ MAXRECV + 1 ];

s = "";

memset ( buf, 0, MAXRECV + 1 );

int status = ::recv ( m_sock, buf, MAXRECV, 0 );

if ( status == -1 )
{
cout << "status == -1 errno == " << errno << " in Socket::recv\n";
return 0;
}
else if ( status == 0 )
{
return 0;
}
else
{
s = buf;
return status;
}
}

// integer empfangen
int Socket::recv ( int& s ) const
{
//char buf [ MAXRECV + 1 ];
int buf;

//s=0;

//memset ( buf, 0, MAXRECV + 1 );

// das ist line 166 (die nächste)
int status = ::recv ( m_sock, buf, MAXRECV, 0 );

if ( status == -1 )
{
cout << "status == -1 errno == " << errno << " in Socket::recv\n";
return 0;
}
else if ( status == 0 )
{
return 0;
}
else
{
s = buf;
return status;
}
}

panzi
29-04-2005, 17:39
Tipp:

// Für alle POD Typen:
template< typename Type >
bool Socket::send ( const Type & value )
{
return ::send ( m_sock, &value, sizeof(Type), MSG_NOSIGNAL ) == sizeof(Type);
}

// speziallisierung für String:
template<>
bool Socket::send<char*>( const char * str )
{
return ::send ( m_sock, str, strlen(str), MSG_NOSIGNAL ) == strlen(str);
}

template<>
bool Socket::send<std::string>( const std::string & str )
{
return ::send ( m_sock, str.c_str(), str.size(), MSG_NOSIGNAL ) == str.size();
}


Hinweis:
Unter big-endian Palttformen (Mac) und little-endian Plattformen (PC) liegen die Daten in anderer Reihenfolge im Speicher. Also wenn du integers versendest und dein Programm unter Mac und PC laufen können soll und eine Mac Version auch mit einer PC Version reden können soll, musst du htons, htonl usw. verwenden. --> man htons (http://unixhelp.ed.ac.uk/CGI/man-cgi?htons)
Vieleicht ne Templatespeziallisierung für die entsprechenden Integers?

Und ich würde die Funktion nicht const machen, es wird ja was geändert (du sendest etwas, das könnte man als Änderunge interpretieren, wie ein schreiben in eine Datei).

moedule
29-04-2005, 18:40
Hinweis:
Unter big-endian Palttformen (Mac) und little-endian Plattformen (PC) liegen die Daten in anderer Reihenfolge im Speicher. Also wenn du integers versendest und dein Programm unter Mac und PC laufen können soll und eine Mac Version auch mit einer PC Version reden können soll, musst du htons, htonl usw.

danke für die tips mit den templates

den gag mit little und big endian hatte ich schon mal, bin damals fast daran verwzeifelt, weil ich einfach nicht dran gedacht hab, hab mich nur gewundert warum mein programm beim mac immer einen scheiß ausgegeben hat


moe

moedule
29-04-2005, 23:37
hmpf, irgendwie stell ich mich jetzt vielleicht etwas doof an

das hier hab ich gebastelt, (erstmal noch ohne templates) und leider will es nicht so wie ich mir das vorstelle
kann mir da jemand meinen logischen fehler sagen?




// integer empfangen
int Socket::recv ( int& s ) const
{
int status = ::recv ( m_sock, &s, sizeof(int), 0 );

if ( status == -1 )
{
cout << "status == -1 errno == " << errno << " in Socket::recv\n";
return 0;
}
else if ( status == 0 )
{
return 0;
}
else
{
s = buf;
return status;
}
}


jetzt wird ne adresse ? übertragen, auf jedenfall kommt immer die selbe zahl egal was ich für einen int übertrage

bei übergabe eines ints krieg ich auf der anderen seite -1073743264

aber ich denke jetzt wirds etwas zu speziell, vielleicht muß ich nochmal das ganze neu aufziehen?
moe

Joghurt
30-04-2005, 00:30
Was soll das s = buf denn?

moedule
30-04-2005, 00:55
Was soll das s = buf denn?

nix mehr ist ein überbleibsel von dem code den ich mal kopiert hab, der für die strings

moe

moedule
30-04-2005, 02:22
leider finde ich im netz keine so richtig schöne anleitung für ne socket implementierung in c++ (mal nicht c , also ohne structs und solche sachen)

vielleicht hat ja doch mal jemand lust sich das ganze anzuschauen, und es mal selber compilieren

http://leia.physik.uni-konstanz.de/~bubek/tmp/socket/

irgendwie hab ich das doch noch nicht so ganz begriffen, wie machr ihr den sowas? oder doch nicht den komplett schönen c++ weg? doch leiber etwas mehr funktionen (anstatt >> und << operatoren)?


geklaut hab ich das hier
http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html
moe

Joghurt
30-04-2005, 12:08
nix mehr ist ein überbleibsel von dem code den ich mal kopiert hab, der für die stringsWas denn jetzt? Steht es noch im Code oder nicht? Das überschriebt nämlich den "Rückgabewert" s.

moedule
30-04-2005, 13:40
au verdammt, wo du recht hast ... hast du recht

moe

moedule
04-05-2005, 02:22
nun, vielleicht muß ich wirklich nochmal von vorne anfangen, jetzt wo ich diese stelle mit dem überschreiben des rückgabewertes gelöscht hab geht gar nichts mehr

moe