Code:
#include <winsock.h>
#include <iostream.h>
#include <memory.h>
#include <process.h>
// Prototype functions
SOCKET establish(unsigned short portnum);
void Skelton_Server(void);
void do_something(SOCKET s);
SOCKET Skelton_Client(const char *hostname, unsigned short portnum);
void CleintDoSomething(SOCKET s);
int read_data(SOCKET s,char* buf,int n);
int write_data(SOCKET s,char* buf,int n);
const unsigned short PortNum=5000; // random port number
void KeyboardThread(void *s);
int main(int argc, char* argv[])
{
try
{
WSADATA info; // some sorta of struct
// WSAStartup must be called fist when init winsock it takes the version number of winsock using in this
// case 1.1 as a word ( MakeWord function does that ). The second param is the address of the WSADATA struct
// it will return 0 if sucessful
if(WSAStartup(MAKEWORD(1,1),&info)!=0)
{
throw("intilizing Winsock failed");
}
char choice;
cout<<"Is this a server ?\t";
cin>>choice;
switch(choice)
{
case 'y':
case 'Y':
Skelton_Server();
break;
case 'n':
case 'N':
char name[32];
SOCKET s;
cout<<"Type in name of Server computer: \t";
cin>>name;
s=Skelton_Client(name,PortNum);
if(s==INVALID_SOCKET){throw("could not connect");}
CleintDoSomething(s);
break;
default:
throw("Unknown command");
break;
}
}
catch(char* error)
{
cout<<error<<"\n";
WSACleanup(); // Clean up Winsock
return 0;
}
WSACleanup(); // Clean up Winsock
return 0;
}
// This function establishes a socket binds it to address
SOCKET establish(unsigned short portnum)
{
// Establish a socket
SOCKET s; // Must ! be in try block cause ! seen outside of {}
try
{
char name[256];
sockaddr_in sa;
hostent *hp;
ZeroMemory(&sa,sizeof(sockaddr_in)); // clr mem
gethostname(name,sizeof(name)); //our name ?
hp=gethostbyname(name); // find address info
if(hp==NULL){throw("Invalid Socket");}
sa.sin_family=hp->h_addrtype; // this is the host address
sa.sin_port=htons(portnum);
// Create Socket ,AF_INET flag makes work on internet only
s=socket(AF_INET,SOCK_STREAM,0);
if(s==INVALID_SOCKET){throw("Invalid Socket");}
// bind socket to the internet address , ie it gives
// address to what it is listening to ( ie server)
if(bind(s,(sockaddr*)&sa,sizeof(sockaddr_in))==SOCKET_ERROR)
{
throw(1);
}
}
catch(char* error)
{
cout<<error<<"\n";
return INVALID_SOCKET;
}
catch(...)
{
cout<<"Socket Error"<<"\n";
closesocket(s);
return INVALID_SOCKET;
}
listen(s,3); // allow max of 3 packets in que
return (s);
}
// Skelton server that waits 4 incoming calls using accept function
// So this creates socket that waits for incoming calls
void Skelton_Server(void)
{
SOCKET s;
if((s=establish(PortNum))==INVALID_SOCKET){exit(1);return;}
// Wait 4 phone calls
for(;;)
{
SOCKET new_sock= accept(s,NULL,NULL);
if(s==INVALID_SOCKET){exit(1);}
do_something(new_sock);
closesocket(new_sock);
break;
}
return;
}
// This is a client function that creates a socket (phone line)
// that instead of waiting for calls , connects to a server socket
// & phones it up ( connects to it). Allowing data to be transfered
// through sockets
SOCKET Skelton_Client(const char *hostname, unsigned short portnum)
{
sockaddr_in sa;
hostent *hp;
SOCKET s;
hp=gethostbyname(hostname);
if(hp==NULL){return INVALID_SOCKET;}
// Clrs the memory in struct
ZeroMemory(&sa,sizeof(sockaddr_in));
// Set mem address
memcpy((char*)&sa.sin_addr,hp->h_addr,hp->h_length);
sa.sin_family=hp->h_addrtype;
sa.sin_port=htons((u_short)portnum);
s=socket(hp->h_addrtype,SOCK_STREAM,0);
if(s==INVALID_SOCKET){return INVALID_SOCKET;}
if(connect(s,(struct sockaddr*)&sa,sizeof(sa))==SOCKET_ERROR)
{
closesocket(s);
return INVALID_SOCKET;
}
return s;
}
// Does stuff with new socket
void do_something(SOCKET s)
{
_beginthread( KeyboardThread, 0, (void *) (s) );
while(true)
{
char buffer[256];
for(int i=0;i<256;i++){buffer[i]='\0';}
int j=read_data(s,buffer,sizeof(buffer));
if(j!=-1){cout<<buffer<<"\n";} // output data passed
}
return;
}
// Does stuff for client
void CleintDoSomething(SOCKET s)
{
_beginthread( KeyboardThread, 0, (void *) (s) );
// Waits 4 data writes something sends it then waits
while(true)
{
char buffer[256];
for(int i=0;i<256;i++){buffer[i]='\0';}
int j=read_data(s,buffer,sizeof(buffer));
if(j!=-1){cout<<buffer<<"\n";} // output data passed
}
return;
}
int read_data(SOCKET s,char* buf,int n)
{
int bcount=0;
int br=0;
while(bcount<n)
{
if((br=recv(s,buf,n-bcount,0))>0)
{
bcount+=br;
buf+=br;
}
else if(br<0)
{
return -1;
}
}
return bcount;
}
int write_data(SOCKET s,char* buf,int n)
{
int bcount=0;
int br=0;
while(bcount<n)
{
if((br=send(s,buf,n-bcount,0))>0)
{
bcount+=br;
buf+=br;
}
else if(br<0)
{
return -1;
}
}
return bcount;
}
// Info socket is like some sorta of communication. So when u make
// a socket its like connecting a phone line. There a diffrent types
// of sockets ( the one we use is Internet AF_INET).
void KeyboardThread(void *s)
{
SOCKET sock = (SOCKET) s;
while(true)
{
char string[256];
for(int i=0;i<256;i++){string[i]='\0';}
cin>>string;
write_data(sock,string,sizeof(string));
}
/* _endthread given to terminate */
_endthread();
return;
}