//WARNING! NO UNITTESTS
#include <stdio.h>
#include <string.h>
#include "socket.h"
//main line for "classes in C" example
//c++ equivalents are show with a c++: comment
int main()
{
char buf[1024];
//c++: socket* s = new socket("127.0.0.1", 80);
INSTP s = new_socket("127.0.0.1", 80);
//c++: s->connect();
connect_socket(s);
sprintf(buf, "GET /cgi-bin/test.cgi HTTP/1.0\r\n\n\n");
//c++: s->send(buf, strlen(buf));
send_socket(s, buf, (int) strlen(buf));
for(;;)
{
//c++: avail = s->avail();
unsigned long avail = avail_socket(s);
if (avail == 0)
break;
memset(buf, 0, sizeof(buf));
//c++: s->recv(buf, sizeof(buf));
recv_socket(s, buf, sizeof(buf));
}
//c++: delete s;
dtor_socket(s);
return 0;
}
|
#ifndef socket_h
#define socket_h
//if socket used other classes,
//they'd be #included here and a #undef CLASS
//would need to be added just before the #define CLASS
//define some helper macros
#include "classdefs.h"
INSTP PUBLIC(socket, new) ( char* ipaddr, int port);
void PUBLIC(socket, dtor) (THISP);
void PUBLIC(socket, connect) (THISP);
void PUBLIC(socket, send) (THISP, char* buf, int len);
void PUBLIC(socket, recv) (THISP, char* buf, int maxlen);
unsigned long PUBLIC(socket, avail) (THISP);
#endif
|
#include <stdio.h>
#include <winsock2.h>
#include "socket.h"
#define SET_THIS() socket_class* this = (socket_class*) thisparm
#define NEW_THIS() malloc(sizeof(socket_class));
//bool for emulating cpp
typedef enum {false, true} bool;
//define the object instance
typedef struct socket_classt
{
SOCKET s;
bool isOpen;
SOCKADDR_IN addr;
u_short port;
} socket_class;
//private prototypes
void PRIVATE(socket, startup) (THISP);
void PRIVATE(socket, cleanup) (THISP);
void PRIVATE(socket, close) (THISP);
void PRIVATE(socket, open) (THISP);
void PRIVATE(socket, fillSocketAddress) (THISP, char* ipaddr);
//public from here on
//the constructor
INSTP PUBLIC(socket, new)(char* ipaddr, int port)
{
socket_class* this = NEW_THIS();
this->s = 0;
this->isOpen = true;
this->port = port;
fillSocketAddress(this, ipaddr);
startup(this);
return this;
}
//the destructor
void PUBLIC(socket, dtor)(THISP)
{
SET_THIS();
cleanup(this);
free(this);
}
//establish the connection
void PUBLIC(socket, connect)(THISP)
{
SET_THIS();
int rc;
int gle;
open(this);
if (!this->isOpen) return;
rc = connect(this->s, (SOCKADDR *)&this->addr, sizeof(SOCKADDR_IN));
if (rc)
gle = WSAGetLastError();
}
//send a packet
void PUBLIC(socket, send)(THISP, char* buf, int len)
{
SET_THIS();
int rc;
int gle;
if (!this->isOpen) return;
rc = send(this->s, buf, len, 0);
if (rc)
gle = WSAGetLastError();
}
//receive a packet
void PUBLIC(socket, recv)(THISP, char* buf, int maxlen)
{
SET_THIS();
int rc;
int gle;
if (!this->isOpen) return;
rc = recv(this->s, buf, maxlen, 0);
if (rc)
gle = WSAGetLastError();
}
//return how many bytes are available to read
unsigned long PUBLIC(socket, avail)(THISP)
{
SET_THIS();
int rc;
int gle;
u_long arg;
if (!this->isOpen) return 0;
arg = 0;
rc = ioctlsocket (this->s, FIONREAD, &arg);
if (rc)
{
gle = WSAGetLastError();
return 0;
}
return arg;
}
//private from here on
//establish the WSA environment
void PRIVATE(socket, startup) (THISP)
{
//SET_THIS();
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 );
WSAStartup(wVersionRequested, &wsaData );
}
//create the socket
void PRIVATE(socket, open) (THISP)
{
SET_THIS();
int gle;
this->s = socket(AF_INET, SOCK_STREAM, 0);
if (this->s == INVALID_SOCKET)
gle = WSAGetLastError();
else
this->isOpen = true;
}
//close the socket
void PRIVATE(socket, close) (THISP)
{
SET_THIS();
if (!this->isOpen) return;
closesocket(this->s);
this->isOpen = false;
}
//ensure the socket is close and kill the WSA environment
void PRIVATE(socket, cleanup) (THISP)
{
SET_THIS();
close(this);
WSACleanup( );
}
//populate the addr structure based on the ipaddr and port
void PRIVATE(socket, fillSocketAddress) (THISP, char* ipaddr)
{
SET_THIS();
memset(&this->addr, 0, sizeof(SOCKADDR_IN));
this->addr.sin_family = AF_INET;
this->addr.sin_port = htons(this->port);
//todo: convert string to an actual addr
this->addr.sin_addr.S_un.S_un_b.s_b1 = 127;
this->addr.sin_addr.S_un.S_un_b.s_b2 = 0;
this->addr.sin_addr.S_un.S_un_b.s_b3 = 0;
this->addr.sin_addr.S_un.S_un_b.s_b4 = 1;
}
|