olemedkrutt Skrevet 19. november 2006 Del Skrevet 19. november 2006 Jeg gidder ikke å skrive så masse winsock kode, noen tips ? Lenke til kommentar
Giddion Skrevet 19. november 2006 Del Skrevet 19. november 2006 Jeg vet ikke hva du skal bruke det til, men se A8 på dennesiden Lenke til kommentar
Dead_Rabbit Skrevet 20. november 2006 Del Skrevet 20. november 2006 (endret) Jeg skrev en veldig enkel wrapper rundt POSIX sockets. Den burde funke under Win32 uten store forandringer. client.hpp Klikk for å se/fjerne innholdet nedenfor #ifndef _client_hpp_ #define _client_hpp_ #include <string> #include <sys/types.h> #include <netdb.h> #include "connection.hpp" namespace Zsocket { class Client { public: Client(); void set_port(short); short get_port() const; void set_host(std::string); std::string get_host() const; Connection connect(); Connection connect(const std::string, int); private: Client(Client&); Client& operator=(Client&); sockaddr_in server; bool host_set; bool port_set; }; } #endif client.cpp Klikk for å se/fjerne innholdet nedenfor #include <iostream> #include <exception> #include <string> #include <cstdlib> #include <sys/socket.h> #include <sys/types.h> #include "client.hpp" #include "exception.hpp" namespace Zsocket { Client::Client() : host_set(false), port_set(false) { } void Client::set_port(short p) { server.sin_port = htons(p); port_set = true; } void Client::set_host(const std::string hn) { hostent* he = gethostbyname(hn.c_str()); if(he == 0) { herror("gethostbyname"); throw Exception("Unable to resolve host"); } server.sin_addr = *((in_addr*)he->h_addr); host_set = true; } Connection Client::connect() { if(!port_set || !host_set) throw Exception("Host and port most be set before connecting"); server.sin_family = AF_INET; memset(&(server.sin_zero), '\0', 8); int sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd == -1) { perror("socket"); throw Exception("Unable to get socket file descriptor"); } if(::connect(sockfd, (sockaddr*)&server, sizeof(sockaddr)) == -1) { perror("connect"); throw Exception("Unable to connecto to server"); } return Connection(sockfd); } Connection Client::connect(const std::string hn, int p) { set_host(hn); set_port(p); return connect(); } } connection.hpp Klikk for å se/fjerne innholdet nedenfor #ifndef _connection_hpp_ #define _connection_hpp_ #include <string> namespace Zsocket { class Connection { public: Connection(int); Connection(const Connection&); std::string read(int); int write(const std::string); bool active(); void close(); private: int sockfd; bool connection_active; }; } #endif connection.cpp Klikk for å se/fjerne innholdet nedenfor #include <cstdlib> #include <sys/socket.h> #include "connection.hpp" #include "exception.hpp" namespace Zsocket { Connection::Connection(int sfd) : sockfd(sfd) { } Connection::Connection(const Connection& cc) { sockfd = cc.sockfd; connection_active = true; } std::string Connection::read(int ss) { char ret[ss]; if(recv(sockfd, &ret, ss, 0) == -1) { perror("recv"); throw Exception("Error while receiving data"); } return ret; } int Connection::write(const std::string buf) { int sent_bytes = send(sockfd, buf.c_str(), buf.length()+1, 0); if(sent_bytes == -1) { perror("send"); throw Exception("Error while sending data"); } return sent_bytes; } bool Connection::active() { return connection_active; } void Connection::close() { ::close(sockfd); } } server.hpp Klikk for å se/fjerne innholdet nedenfor #ifndef _server_hpp_ #define _server_hpp_ #include <string> #include <cerrno> #include <cstdlib> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> #include "connection.hpp" namespace Zsocket { class Server { public: Server(); void listen(short); Connection accept(); private: sockaddr_in server; sockaddr_in client; int sockfd; int backlog; }; } #endif server.cpp Klikk for å se/fjerne innholdet nedenfor #include <exception> #include "server.hpp" namespace Zsocket { Server::Server() : backlog(20) { sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd == -1) { perror("socket"); } server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; memset(&(server.sin_zero), '\0', 8); } void Server::listen(short port) { server.sin_port = htons(port); if(bind(sockfd, (sockaddr*)&server, sizeof(sockaddr)) == -1) { perror("bind"); } if(::listen(sockfd, backlog) == -1) { perror("listen"); } } Connection Server::accept() { socklen_t len = sizeof(sockaddr); int sfd = ::accept(sockfd, (sockaddr*)&client, &len); if(sfd == -1) perror("accpt"); Connection conn(sfd); return conn; } } exception.hpp Klikk for å se/fjerne innholdet nedenfor #ifndef _exception_hpp_ #define _exception_hpp_ #include <string> namespace Zsocket { class Exception { public: Exception(std::string ee) : errmsg(ee) { }; std::string what() { return errmsg; }; private: std::string errmsg; }; } #endif Den er som du ser ekstremt enkel, kanskje i det ytterste laget, men den funker for meg. Dessuten bør den ikke være vanskelig utvide hvis ønsket. Edit: For at den skal funke i windows, må headerene byttes ut, og så må det legges til en WSA_Startup elns et eller annet sted. Endret 20. november 2006 av zirener Lenke til kommentar
olemedkrutt Skrevet 21. november 2006 Forfatter Del Skrevet 21. november 2006 Hvilken av filene skal jeg include for å få det til å funke? Kan du vise meg hvordan man får f.eks opp opp en server? Lenke til kommentar
Dead_Rabbit Skrevet 22. november 2006 Del Skrevet 22. november 2006 (endret) Nå vet ikke jeg hva du bruker av utviklingsverktøy, men ettersom jeg bruker SCons, bruker jeg følgende SConstruct-fil: # Zsocket build env = Environment() env.SharedLibrary('zsocket', Split(""" src/client.cpp src/server.cpp src/connection.cpp """)) og kompilerer på følgende måte: staale@thinkpad:~/programming/cpp/zsocket$ scons Da får jeg i Linux en .so fil, noe som i Windows vil tilsvare en .dll fil. Denne bruker jeg når jeg linker serveren med programmet på dette viset: # server build server = Environment() server.Append(CPPPATH='..', LIBPATH='..', LIBS='zsocket') server.Program('server', Split(""" server.cpp """)) Her har jeg satt CPPPATH til '..', altså "mappen ett hakk tilbake", og det samme har jeg gjort med LIBPATH. Dette vil jo selvfølgelig variere alt ettersom hvor man har prosjektet sitt. I mitt tilfelle, er det i test-mappa i mappen der jeg har kompilert bibloteket, og da blir verdiene til CPPPATH og LIBPATH '..'. staale@thinkpad:~/programming/cpp/zsocket/test$ scons Kjører... staale@thinkpad:~/programming/cpp/zsocket/test$ ./server Kildekoden til serveren: #include <iostream> #include <sstream> #include <server.hpp> #include <connection.hpp> using namespace std; using namespace Zsocket; int main(int argc, char* argv[]) { Server server; server.listen(2507); while(true) { Connection conn = server.accept(); string buffer = conn.read(255); conn.write("This is the server speaking!"); conn.close(); } return 0; } Skrik om det var noe som var utydelig. Endret 22. november 2006 av zirener Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå