 
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, 20: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, 23: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, 23: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, 23: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.