View Full Version : Socket Win-Lin
#ifndef SOCK_HPP
#define SOCK_HPP
#ifdef WIN32
#include <winsock2.h>
typedef SOCKET sock_t;
#define CLOSE(x) closesocket(x); WSACleanup();
#define SEND(sck, msg) send(sck, msg, sizeof(msg), 0);
#define RECV(sck, msg) recv(sck, msg, sizeof(msg), 0);
#elif def LINUX
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
typedef int sock_t;
#define CLOSE(x) close(x);
#define SEND(sck, msg) write(sck,msg,strlen(msg))
#define RECV(sck, msg) read(sck,msg,strlen(msg))
#endif
#endif
Questo colma le leggeredifferenze tra win e lin riguardo ai socket??
Tnk
ilsensine
17-05-2004, 19:44
Sì e no.
Innanzitutto una nota cosmetica: nelle macro non aggiungere il ";" (altrimenti negli if...else sei fregato).
Per lo stesso motivo, se hai
#define a(x) b(x); c(x);
dovresti scrivere
#define a(x) do { \
b(x); \
c(x); } while(0)
Riguardo al codice, non usare WSACleanup quando chiudi il socket, in quanto potresti voler aprire più socket (WSAStartup va chiamata solo all'apertura del primo socket, e la cleanup solo alla chiusura dell'ultimo, o dell'applicazione).
Infine, usa anche nella versione linux le funzioni send e recv -- sono praticamente le stesse che su windows.
ecco il code finale:
#ifndef SOCK_HPP
#define SOCK_HPP
#include <iostream>
/// Safe Array deleting
#define ARRAY_SAFE_DELETE(ptr) delete[] ptr; ptr = NULL;
///
/// This is a generalization of socket
///
typedef int sock_t;
#ifdef __WIN__
//#warning "Win32 Mode On"
#include <winsock2.h>
#define CLOSE(x) closesocket(x);
#define SEND(sck, msg) send(sck, msg, sizeof(msg), 0)
#define RECV(sck, msg) recv(sck, msg, sizeof(msg), 0)
#elif defined(__LINUX__)
#warning "Linux Mode On"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define CLOSE(x) close(x);
#define SEND(sck, msg) write(sck,msg,strlen(msg))
#define RECV(sck, msg) read(sck,msg,strlen(msg))
#endif
/// The Error Enum
enum
{
ERR_SOCK_INVALID = 0x0, /// invalid socket
ERR_SOCK_CONNECT, /// error in connection
ERR_SOCK_SEND, /// error in send
ERR_SOCK_RECV, /// error in recv
};
///
/// Client Socket
///
class CClientSocket
{
private:
sock_t my_socket;
#ifdef __WIN__
WSAData wsaData;
#endif
struct hostent *host_entry;
struct sockaddr_in server;
public:
CClientSocket();
~CClientSocket();
int Build(const std::string addr, unsigned short port);
void Close();
int Read(char *buf);
int Write(char *buf);
};
CClientSocket::CClientSocket()
{
#ifdef __WIN__
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
}
CClientSocket::~CClientSocket()
{
}
int CClientSocket::Read(char *buf)
{
if(RECV(my_socket, buf) != 0)
return ERR_SOCK_RECV;
return 0;
}
int CClientSocket::Write(char *buf)
{
if(SEND(my_socket, buf) != 0)
return ERR_SOCK_SEND;
return 0;
}
int CClientSocket::Build(const std::string addr, unsigned short port)
{
my_socket = socket(AF_INET,SOCK_STREAM,0);
host_entry = gethostbyname(addr.c_str());
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = *(unsigned long*) host_entry->h_addr;
if(connect(my_socket, (sockaddr*)&server, sizeof(server)) != 0)
return ERR_SOCK_CONNECT;
return 0;
}
void CClientSocket::Close()
{
CLOSE(my_socket)
}
#endif
ilsensine
17-05-2004, 22:44
A parte il fatto che hai ignorato metà dei miei suggerimenti ( :D ), ti INVITO, come ti ho già detto un'altra volta, a correggere questa CASTRONERIA:
#define RECV(sck, msg) recv(sck, msg, sizeof(msg), 0)
Mi ascolti, eh? :D
ilsensine
17-05-2004, 22:46
Anche queste sono castronerie ;)
if(RECV(my_socket, buf) != 0) return ERR_SOCK_RECV;
if(SEND(my_socket, buf) != 0) return ERR_SOCK_SEND;
ilsensine
17-05-2004, 22:49
Altre imprecisioni minori:
my_socket = socket(AF_INET,SOCK_STREAM,0);
Non controlli il valore di ritorno nel caso che la socket fallisca.
host_entry = gethostbyname(addr.c_str());
Se l'host non esiste/non è raggiungibile, la funzione ritorna NULL.
Attenzione se fai applicazioni multithread: la gethostbyname non è "reentrant" (almeno su linux; esiste la gethostbyname_r)
if(connect(my_socket, (sockaddr*)&server, sizeof(server)) != 0)
return ERR_SOCK_CONNECT;
Se la connect fallisce, chi libera il socket che hai allocato poche righe sopra?
tnk x i suggerimenti.
Ora li mettero in pratica :D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.