# 9 Re: SetTimeOut for Winsock2 in C
Fixed smiles
The examples in visual studio 6.0 are in C (or nearly so, its supposedly C++).
Starting with .net microsoft hid the low level examples.
The following class was created from those C examples, which I can no longer find.
It is basically C in the class methods. I wrote it assuming threaded apps but that is not required if you use the nonblocking IO statements provided by Peter. Anyway, this might help you create the C you need, if not throw it away.
//// .h file
/*simple udp and tcp library
This is supposed to be able to perform most udp and tcp functions.
I am not sure how much of tcp works anymore; UDP is working well.
*/
#ifndef jcomm_file
#define jcomm_file
#define WIN32_LEAN_AND_MEAN
typedef int socklen_t;
#include <afxwin.h> //threads
#include <winsock.h> //this one messes up in .net, the other in 6.0 so whatever
//#include <winsock2.h> //the example included this but it causes problems!
typedef float float_data_t[1024]; //you could make this something else, a struct, etc.
const int size_of_datagram = 4096;
//I assume here that a float is 4 bytes ! seems fair as this stuff needs visual studio to compile...
//tc uses send to send from server back to client, udp uses sendto, I did not have a use for this yet.
struct jcomm_t
{
char *host;
unsigned int port;
char data[size_of_datagram];
bool udp; //udp or tcpip?
void jcomm_t::jcomm_client_init(int portnum, char * host_name, bool is_udp);
void jcomm_t::jcomm_client_send(); //example mostly (use sendto instead)
void jcomm_t::jcomm_server_init(int portnum, bool is_udp);
void jcomm_t::jcomm_server_start(); //example do not use
void jcomm_t::jcomm_cleanup(); //?? it may break all sockets not just this one
static bool jcomm_show_error(); //the help text for each code is printed
sockaddr_in server, local, from;
PHOSTENT phostent;
WSADATA WSAData;
SOCKET WinSocket,tcsocket;
unsigned int Addr;
int fromlen;
};
#endif
------ //end .h
//1-31-05 -- borrows heavily from microsoft examples --
#include "udp-tcp.h"
#include <iostream>
using namespace std;
void jcomm_t::jcomm_client_init(int portnum, char * host_name, bool is_udp)//func
{
// Notice that almost nothing in this code is specific to whether we
// are using UDP or TCP. The socket open command is the only place.
// When connect() is called on a udp socket, it does not
// actually establish the connection as a TCP socket
// would. Instead, TCP establishes the remote half of the
// ( LocalIPAddress, LocalPort, RemoteIP, RemotePort) mapping.
// This enables us to use send() and recv() on datagram sockets,
// instead of recvfrom() and sendto() -- making this a generic object
//suited for either tcp or udp transmission
port = portnum;
host = host_name;
udp = is_udp;
WSAStartup(0x202,&WSAData); //X202 is 514 decimal, it is the 'version required' of something or other.
if (isalpha(host[0])) //if its a Name or a number, we can open it either way
{
phostent = gethostbyname(host);
}
else
{
Addr = inet_addr(host);
phostent = gethostbyaddr((char *)&Addr,4,AF_INET);
}
memset(&server,0,sizeof(server));
memcpy(&(server.sin_addr),phostent ->h_addr,phostent ->h_length);
server.sin_family = phostent ->h_addrtype;
server.sin_port = htons(port);
if(udp)
WinSocket = socket(AF_INET,SOCK_DGRAM,0); // Open a socket udp style
else
{
WinSocket = socket(AF_INET,SOCK_STREAM,0); // Open a socket tcp style
}
/*
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY; //inet_addr("204.130.141.139"); //could be set to an ip address
local.sin_port = htons(port);
cout << local.sin_port << endl;
bool val = true;
setsockopt(WinSocket,IPPROTO_IP,SO_REUSEADDR, (char *) &val, sizeof(bool));
bind(WinSocket,(sockaddr*)&local,sizeof(local) );
*/
connect(WinSocket ,(sockaddr*)&server,sizeof(server)) ;
/*
sockaddr getsa;
int namelen;
getsockname (WinSocket,&getsa, &namelen );
int x;
for(x = 0; x < namelen; x++)
printf("%x",getsa.sa_data[x]);
cout << endl;
*/
jcomm_show_error();
}
void jcomm_t::jcomm_client_send()//func
{
send(WinSocket, data, size_of_datagram ,0);
}
void jcomm_t::jcomm_server_init(int portnum, bool is_udp)//func
{
port = portnum;
udp = is_udp;
WSAStartup(0x202,&WSAData);
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY; //could be set to an ip address
local.sin_port = htons(port);
if(udp)
WinSocket= socket(AF_INET, SOCK_DGRAM ,0); //udp
else
WinSocket= socket(AF_INET, SOCK_STREAM,0); //tcp
bind(WinSocket,(sockaddr*)&local,sizeof(local) );
// We cannot listen() on a UDP socket.
fromlen =sizeof(from);
if (!udp)
{
listen(WinSocket,100);
tcsocket = accept(WinSocket,(struct sockaddr*)&from, &fromlen);
inet_ntoa(from.sin_addr),
htons(from.sin_port) ;
/**/
}
else
tcsocket = WinSocket;
}
//the threads should be customized to handle your packets or do what you need
//they are provided as examples / templates !
UINT jcomm_tcpip_thread(LPVOID pointer)//func
{
jcomm_t * pj = (jcomm_t *) pointer;
listen(pj->WinSocket,5);
pj->fromlen =sizeof(pj->from);
pj->tcsocket = accept(pj->WinSocket,(sockaddr*)&(pj->from), &(pj->fromlen));
inet_ntoa(pj->from.sin_addr);
htons(pj->from.sin_port) ;
/*
for(;;)
{
recv(pj->tcsocket,pj->data,size_of_datagram,0 );
//process data here
}
*/
return 0;
}
UINT jcomm_udp_thread(LPVOID pointer)//func
{
jcomm_t * pj = (jcomm_t *) pointer;
for(;;)
{
recvfrom(pj->tcsocket,pj->data,size_of_datagram,0,
(sockaddr *)&(pj->from),&(pj->fromlen));
//process data here
}
return 0;
}
void jcomm_t::jcomm_server_start()//func
{
if(udp)
AfxBeginThread(jcomm_udp_thread, this, THREAD_PRIORITY_LOWEST, 0, 0, NULL);
else
AfxBeginThread(jcomm_tcpip_thread, this, THREAD_PRIORITY_LOWEST, 0, 0, NULL);
}
void jcomm_t::jcomm_cleanup()//func
{
closesocket(WinSocket);
WSACleanup();
}
jonnin at 2007-11-11 21:09:13 >

# 10 Re: SetTimeOut for Winsock2 in C
The show error function made the post too long:
bool jcomm_t::jcomm_show_error()//func
{
int err = WSAGetLastError();
switch(err)
{
case WSAEINTR: cout << "Interrupted system call.\n"; break;
case WSAEBADF: cout << "Bad file number.\n"; break;
//case WSEACCES: cout << "Permission denied.\n"; break; //no longer supported?
case WSAEFAULT: cout << "Bad address.\n"; break;
case WSAEINVAL: cout << "Invalid argument.\n"; break;
case WSAEMFILE: cout << "Too many open files.\n"; break;
//case WSAEWOULDBLOCK: cout << "Operation would block.\n"; break; //annoying non-important msg
case WSAEINPROGRESS: cout << "Operation now in progress. any Windows Sockets API function called while a blocking function is in progress.\n"; break;
case WSAEALREADY: cout << "Operation already in progress.\n"; break;
case WSAENOTSOCK: cout << "Socket operation on nonsocket.\n"; break;
case WSAEDESTADDRREQ: cout << "Destination address required.\n"; break;
case WSAEMSGSIZE: cout << "Message too long.\n"; break;
case WSAEPROTOTYPE: cout << "Protocol wrong type for socket.\n"; break;
case WSAENOPROTOOPT: cout << "Protocol not available.\n"; break;
case WSAEPROTONOSUPPORT: cout << "Protocol not supported.\n"; break;
case WSAESOCKTNOSUPPORT: cout << "Socket type not supported.\n"; break;
case WSAEOPNOTSUPP: cout << "Operation not supported on socket.\n"; break;
case WSAEPFNOSUPPORT: cout << "Protocol family not supported.\n"; break;
case WSAEAFNOSUPPORT: cout << "Address family not supported by protocol family.\n"; break;
case WSAEADDRINUSE: cout << "Address already in use.\n"; break;
case WSAEADDRNOTAVAIL: cout << "Cannot assign requested address.\n"; break;
case WSAENETDOWN: cout << "Network is down. This error may be reported at any Time if the Windows Sockets implementation detects failure.\n"; break;
case WSAENETUNREACH: cout << "Network is unreachable.\n"; break;
case WSAENETRESET: cout << "Network dropped connection on reset.\n"; break;
case WSAECONNABORTED: cout << "Software caused connection abort.\n"; break;
case WSAECONNRESET: return true; break;//cout << "Connection reset by peer.\n"; break; //removed -- handled
case WSAENOBUFS: cout << "No buffer space available.\n"; break;
case WSAEISCONN: cout << "Socket is already connected.\n"; break;
case WSAENOTCONN: cout << "Socket is not connected.\n"; break;
case WSAESHUTDOWN: cout << "Cannot send after socket shutdown.\n"; break;
case WSAETOOMANYREFS: cout << "Too many references: cannot splice.\n"; break;
case WSAETIMEDOUT: cout << "Connection timed out.\n"; break;
case WSAECONNREFUSED: cout << "Connection refused.\n"; break;
case WSAELOOP: cout << "Too many levels of symbolic links.\n"; break;
case WSAENAMETOOLONG: cout << "File Name too long.\n"; break;
case WSAEHOSTDOWN: cout << "Host is down.\n"; break;
case WSAEHOSTUNREACH: cout << "No route to host.\n"; break;
case WSASYSNOTREADY: cout << "Returned by WSAStartup(), indicating that the network subsystem is unusable.\n"; break;
case WSAVERNOTSUPPORTED: cout << "Returned by WSAStartup(), indicating that the Windows Sockets DLL cannot support this application.\n"; break;
case WSANOTINITIALISED: cout << "Winsock not initialized. This message is returned by any function except WSAStartup(), indicating that a successful WSAStartup() has not yet been performed.\n"; break;
case WSAEDISCON: cout << "Disconnect.\n"; break;
case WSAHOST_NOT_FOUND: cout << "Host not found. This message indicates that the key (Name, address, and so on) was not found.\n"; break;
case WSATRY_AGAIN: cout << "Nonauthoritative host not found. This error may suggest that the Name service itself is not functioning.\n"; break;
case WSANO_RECOVERY: cout << "Nonrecoverable error. This error may suggest that the Name service itself is not functioning.\n"; break;
case WSANO_DATA: cout << "Valid Name, no data record of requested type. This error indicates that the key(Name, address, and so on) was not found. \n"; break;
default: ; //cout << "No socket errors\n"; //left blank so the call to this can be left in silently
cout.flush();
}
return false;
}
jonnin at 2007-11-11 21:10:10 >
