#include "tnplib.h"
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int SocketLibStart() {
#ifdef WIN32
WSADATA wsaData;
return( WSAStartup(0x0101, &wsaData) );
#else
return(0);
#endif
}
void SocketLibEnd() {
#ifdef WIN32
WSACleanup();
#endif
}
SOCKET TCPStartServer(const int port, const int queue) {
struct protoent *ptrp;
struct sockaddr_in sad;
SOCKET sd;
memset((char *)&sad,0,sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons((u_short)port);
ptrp = getprotobyname("tcp");
if ((char*)(ptrp)==0) {
cerr << "cannot map \"tcp\" to protocol number" << endl;
return(-1);
}
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (int(sd)<0) {
cerr << "socket creation failed" << endl;
return(-1);
}
if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
cerr << "bind failed" << endl;
return(-1);
}
if (listen(sd, queue) < 0) {
cerr << "listen failed" << endl;
return(-1);
}
return(sd);
}
SOCKET TCPWaitForConnection(SOCKET sd) {
struct sockaddr_in cad;
int alen;
alen = sizeof(cad);
return( accept(sd, (struct sockaddr *)&cad, &alen) );
}
int TCPStopServerTCP(SOCKET sd) {
return( closesocket(sd) );
}
SOCKET TCPStartClient(const char *host, const int port) {
struct hostent *ptrh;
struct protoent *ptrp;
struct sockaddr_in sad;
SOCKET sd;
memset((char *)&sad,0,sizeof(sad));
sad.sin_family = AF_INET;
ptrh = gethostbyname(host);
if ((char*)(ptrh)==0) {
cerr << "invalid host: " << host << endl;
return(-1);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
sad.sin_port = htons((u_short)port);
ptrp = getprotobyname("tcp");
if ((char*)(ptrp)==0) {
cerr << "cannot map \"tcp\" to protocol number" << endl;
return(-1);
}
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (int(sd)<0) {
cerr << "soclet creation failed" << endl;
return(-1);
}
if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
cerr << "connection failed" << endl;
return(-1);
}
return(sd);
}
int TCPStopClient(SOCKET sd) {
return( closesocket(sd) );
}
int TCPSetTTL(SOCKET sd, int ttl) {
return( setsockopt(sd,IPPROTO_IP,IP_TTL,(const char*)&ttl,sizeof(ttl)) );
}
int TCPSetTimeout(SOCKET sd, int tout) {
return( setsockopt(sd,SOL_SOCKET,SO_RCVTIMEO,(char*)&tout,sizeof(tout)) );
}
int TCPSetFragment(SOCKET sd, int isOk) {
return(0);
}
int TCPSetNoDelay(SOCKET sd, int isOk) {
#ifdef TCP_NODELAY
return( setsockopt(sd,IPPROTO_TCP,TCP_NODELAY,(char*)&isOk,sizeof(isOk)) );
#else
cerr << "TCP_NODELAY not supported by this platform - option ignored" << endl;
return(0);
#endif
}
int TCPPrepClose(SOCKET sd) {
return( shutdown(sd,SD_BOTH) );
}
int TCPRecvAny(SOCKET sd, char *buffer, const int maxsize) {
return( recv(sd,buffer,maxsize,0) );
}
int TCPRecvLine(SOCKET sd, char *line, const int maxsize) {
int status;
int len=0;
char bch;
while (1) {
status = recv(sd,&bch,1,0);
if (status<0) return(status);
if (len>=maxsize) return(-1);
if (bch=='\n')
{
line[len]='\0';
return(len);
}
else if (bch=='\r')
{
}
else
{
line[len]=bch;
len++;
}
}
}
int TCPRecvDumpLine(SOCKET sd) {
int status;
int len=0;
char bch;
while (1) {
status = recv(sd,&bch,1,0);
if (status<0) return(status);
if (bch=='\n') return(len);
if (bch!='\r') len++;
}
}
int TCPSendAny(SOCKET sd, const char *buffer, int size) {
return( send(sd,buffer,size,0) );
}
int TCPSendLine(SOCKET sd, const char *line) {
return( send(sd,line,int(strlen(line)),0) );
}
SOCKET UDPStartServer(const int port) {
return( UDPStartMServer(port, 0) );
}
SOCKET UDPStartMServer(const int port, int multiple) {
struct protoent *ptrp;
struct sockaddr_in sad;
SOCKET sd;
memset((char*)&sad,0,sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons((u_short)port);
ptrp = getprotobyname("udp");
if ((char*)(ptrp)==0) {
cerr << "cannot map \"udp\" to protocol number" << endl;
return(-1);
}
sd = socket(PF_INET, SOCK_DGRAM, ptrp->p_proto);
if (int(sd)<0) {
cerr << "socket creation failed" << endl;
return(-1);
}
if (multiple!=0 && setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,(char*) &multiple,sizeof(multiple)) <0 ) {
cerr << "reuse address option failed" << endl;
return(-1);
}
if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
cerr << "bind failed" << endl;
return(-1);
}
return(sd);
}
int UDPStopServer(SOCKET sd) {
return( closesocket(sd) );
}
SOCKET UDPStartClient() {
SOCKET sd;
sd=socket(AF_INET,SOCK_DGRAM,0);
if (int(sd)<0) {
cerr << "socket creation failed" << endl;
return(-1);
}
return(sd);
}
int UDPStopClient(SOCKET sd) {
return( closesocket(sd) );
}
int UDPSetTTL(SOCKET sd, int ttl) {
return( setsockopt(sd,IPPROTO_IP,IP_TTL,(const char*)&ttl,sizeof(ttl)) );
}
int UDPSetTimeout(SOCKET sd, int tout) {
return( setsockopt(sd,SOL_SOCKET,SO_RCVTIMEO,(char*)&tout,sizeof(tout)) );
}
int UDPSetFragment(SOCKET sd, int isOk) {
return(0);
}
int UDSetSocketReuse(SOCKET sd, int isOk) {
return( setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,(char*) &isOk,sizeof(isOk)) );
}
int UDPPrepClose(SOCKET sd) {
return( shutdown(sd,SD_BOTH) );
}
int UDPMulticastSetTTL(SOCKET sd, int ttl) {
return( setsockopt(sd,IPPROTO_IP,IP_MULTICAST_TTL,(char*) &ttl,sizeof(ttl)) );
}
int UDPMulticastJoin(SOCKET sd, const char* address) {
struct hostent *ptrh;
struct sockaddr_in sad;
struct ip_mreq mreq;
ptrh = gethostbyname(address);
if ((char*)(ptrh)==0) {
cerr << "invalid host: " << address << endl;
return(-1);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
if(!IN_MULTICAST(ntohl(sad.sin_addr.s_addr))) {
cerr << "invalid multicast address: " << address << endl;
return(-1);
}
mreq.imr_multiaddr.s_addr=sad.sin_addr.s_addr;
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
return( setsockopt(sd,IPPROTO_IP,IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq)) );
}
int UDPMulticastDrop(SOCKET sd, const char* address) {
struct hostent *ptrh;
struct sockaddr_in sad;
struct ip_mreq mreq;
ptrh = gethostbyname(address);
if ((char*)(ptrh)==0) {
cerr << "invalid host: " << address << endl;
return(-1);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
if(!IN_MULTICAST(ntohl(sad.sin_addr.s_addr))) {
cerr << "invalid multicast address: " << address << endl;
return(-1);
}
mreq.imr_multiaddr.s_addr=sad.sin_addr.s_addr;
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
return( setsockopt(sd,IPPROTO_IP,IP_DROP_MEMBERSHIP, (char*) &mreq, sizeof(mreq)) );
}
int UDPRecvAny(SOCKET sd, char *buffer, const int maxsize, sockaddr_in &remoteaddr) {
int alen = sizeof(remoteaddr);
return( recvfrom(sd,buffer,maxsize,0,(sockaddr *)&remoteaddr,&alen) );
}
int UDPSendAny(SOCKET sd, const char *buffer, int size, const sockaddr_in &remoteaddr) {
int alen = sizeof(remoteaddr);
return( sendto(sd,buffer,size,0,(sockaddr *)&remoteaddr,alen) );
}
sockaddr_in CreateAddress(const char* address, const int port) {
struct hostent *ptrh;
struct sockaddr_in sad;
memset((char *)&sad,0,sizeof(sad));
ptrh = gethostbyname(address);
if ((char *)(ptrh)==0) {
cerr << "invalid host: " << address << endl;
return(sad);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
sad.sin_family = AF_INET;
sad.sin_port = htons((u_short)port);
return(sad);
}