// ==========================================================================
// Author: Yee Hsu
// Date: 6/4/2005
// File: Server.cpp
//
// Desc: This is a TCP and UDP multi-server. Server is able to open and
// listen to open connections and allow either TCP or UDP connections.
// Server opens a communication port and allows incomming connections
// to be established with the server. Server performs request
// by taking in request and replying with messages back to the client.
//
// Server accepts connection from either Windows/Linux and can run as
// a Windows service or Linux daemon. Code is written in portable
// format to compile in both Windows/Linux.
// ==========================================================================
/* Global include files for Windows & Unix */
#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#ifdef _WIN32
/* Socket include file for Windows */
#include <winsock.h>
#pragma comment(lib, "wsock32.lib")
#define close(sd) closesocket(sd);
#else
/* Socket include files for Unix */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
/* Global define constants */
#define PORT_NUM 0
#define MAXCLIENT 5
#define MAXBUFFER 256
// macro to return the max of two integers
#define MAX(x,y) ((x) > (y) ? (x) : (y))
// ==========================================================================
// Identifier: main()
//
// Description: main routine. Here is where the program starts.
// ==========================================================================
int main(int argc, char* argv[])
{
// initialize some variables
int usd, tsd, alen, nfds;
struct sockaddr_in sin, tsin;
fd_set rdfs;
char msg[MAXBUFFER];
#ifdef _WIN32
// initialize Winsock DLL files
WORD wVersionRequested;
WSADATA wsaData;
int err = 0;
wVersionRequested = MAKEWORD(2,0);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
printf("Error: unable to initialize WinSock DLL\n");
exit(0);
}
#endif
// lets open a port to take incomming connections
memset(&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(PORT_NUM);
// create a UDP socket
if ((usd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("Error: UDP socket()\n");
exit(0);
}
// bind to the socket
if (bind(usd, (struct sockaddr*) &sin, sizeof(sin)) < 0)
{
printf("Error: UDP bind()\n");
exit(0);
}
alen = sizeof(tsin);
// get the socket name
if (getsockname(usd, (struct sockaddr*) &tsin, &alen) < 0)
{
printf("Error: getsocketname()\n");
exit(0);
}
sin.sin_port = tsin.sin_port;
// create a TCP socket
if ((tsd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Error: TCP socket()\n");
exit(0);
}
// bind to the socket
if (bind(tsd, (struct sockaddr*) &sin, sizeof(sin)) < 0)
{
printf("Error: TCP bind()\n");
exit(0);
}
// listen for incomming connections to your port
if (listen(tsd, MAXCLIENT) < 0)
{
printf("Error: listen()\n");
exit(0);
}
printf("UDP and TCP multiserver online: %d\n", ntohs(tsin.sin_port));
FD_ZERO(&rdfs);
nfds = MAX(usd,tsd) + 1;
// infinite loop, this is where the server runs indefinitely to serve the client
while (1)
{
// connect and server either TCP or UDP connections
FD_SET(tsd, &rdfs);
FD_SET(usd, &rdfs);
// select which channel to support
if (select(nfds, &rdfs, (fd_set*)0, (fd_set*)0, (struct timeval*)0) < 0)
{
printf("Error: select()\n");
exit(0);
}
// serve the TCP connection
if (FD_ISSET(tsd, &rdfs))
{
int sd;
alen = sizeof(sin);
if ((sd = accept(tsd, (struct sockaddr*) &sin, &alen)) < 0)
{
printf("Error: TCP accept()\n");
exit(0);
}
if (recv(sd, msg, sizeof(msg), 0) < 0)
{
printf("Error: TCP recv()\n");
exit(0);
}
//////////////////////////////////////
printf("TCP: %s\n", msg);
strcpy(msg, "GOT IT!");
//////////////////////////////////////
if (send(sd, msg, strlen(msg)+1, 0) < 0)
{
printf("Error: TCP send()\n");
exit(0);
}
close(sd);
}
// server the UDP connection
if (FD_ISSET(usd, &rdfs))
{
alen = sizeof(sin);
if (recvfrom(usd, msg, sizeof(msg), 0, (struct sockaddr*) &sin, &alen) < 0)
{
printf("Error: UDP recvfrom()\n");
exit(0);
}
//////////////////////////////////////
printf("UDP: %s\n", msg);
strcpy(msg, "GOT IT!");
//////////////////////////////////////
if (sendto(usd, msg, sizeof(msg), 0, (struct sockaddr*) &sin, sizeof(sin)) < 0)
{
printf("Error: UDP sendto()\n");
exit(0);
}
}
}
#ifdef _WIN32
// perform all cleanups when connections close
WSACleanup();
#endif
return 0;
}