| Tenouk.com | Winsock Program Example 9 | Main | Winsock Program Example 11 >| Site Index | Download |
WINSOCK 2
WINDOWS SOCKET: PROGRAM EXAMPLES PART 10
|
|
|||||||||||||||||||||||||||||||||||||
|
Winsock Tutorial
|
My Training Period: hours
Note: This is a continuation from previous Module. Machine’s OS is standalone Windows Xp Pro with SP2 except whenever mentioned. Compiler used was Visual C++ 2003 .Net 1.1. Beware the codes that span more than one line. Program examples have been tested for Non Destructive Test :o). All information compiled for Windows 2000 (NT5.0) above and...
Abilities
▪ Able to understand the advanced networking of the TCP/IP. ▪ Able to understand Winsock implementation and operations through the APIs and program examples. ▪ Able to gather, understand and use the Winsock functions, structures and macros in your programs. ▪ Able to build programs that use Microsoft C/Standard C programming language and Winsock APIs.
addrinfo
freeaddrinfo()
|
||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||
Program Example
For the program example that demonstrates the use of the send() functions on server and client please refer to the previous program examples.
Complete client-server program example
The following codes are server and client program examples that used the previous discussed Winsock functions and structures. In this case, to make the client-server communication possible you have to make the server settings (through the arguments- protocol, port number etc.) must match with the client settings. For example if you choose to run the UDP server, the client also must be UDP client. Please run the server program first and you can run the client from different computers. In this example the server and client have been run using the default values of arguments on local Windows Xp Pro machine.
/* Server program example for IPv4 */
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEFAULT_PORT 2007
// default TCP socket type
#define DEFAULT_PROTO SOCK_STREAM
void Usage(char *progname)
{
fprintf(stderr,"Usage: %s -p [protocol] -e [port_num] -i [ip_address]\n", progname);
fprintf(stderr,"Where:\n\t- protocol is one of TCP or UDP\n");
fprintf(stderr,"\t- port_num is the port to listen on\n");
fprintf(stderr,"\t- ip_address is the ip address (in dotted\n");
fprintf(stderr,"\t decimal notation) to bind to. But it is not useful here...\n");
fprintf(stderr,"\t- Hit Ctrl-C to terminate server program...\n");
fprintf(stderr,"\t- The defaults are TCP, 2007 and INADDR_ANY.\n");
WSACleanup();
exit(1);
}
int main(int argc, char **argv)
{
char Buffer[128];
char *ip_address= NULL;
unsigned short port=DEFAULT_PORT;
int retval;
int fromlen;
int i;
int socket_type = DEFAULT_PROTO;
struct sockaddr_in local, from;
WSADATA wsaData;
SOCKET listen_socket, msgsock;
/* Parse arguments, if there are arguments supplied */
if (argc > 1)
{
for(i=1; i<argc; i++)
{
// switches or options...
if ((argv[i][0] == '-') || (argv[i][0] == '/'))
{
// Change to lower...if any
switch(tolower(argv[i][1]))
{
// if -p or /p
case 'p':
if (!stricmp(argv[i+1], "TCP"))
socket_type = SOCK_STREAM;
else if (!stricmp(argv[i+1], "UDP"))
socket_type = SOCK_DGRAM;
else
Usage(argv[0]);
i++;
break;
// if -i or /i, for server it is not so useful...
case 'i':
ip_address = argv[++i];
break;
// if -e or /e
case 'e':
port = atoi(argv[++i]);
break;
// No match...
default:
Usage(argv[0]);
break;
}
}
else
Usage(argv[0]);
}
}
// Request Winsock version 2.2
if ((retval = WSAStartup(0x202, &wsaData)) != 0)
{
fprintf(stderr,"Server: WSAStartup() failed with error %d\n", retval);
WSACleanup();
return -1;
}
else
printf("Server: WSAStartup() is OK.\n");
if (port == 0)
{
Usage(argv[0]);
}
local.sin_family = AF_INET;
local.sin_addr.s_addr = (!ip_address) ? INADDR_ANY:inet_addr(ip_address);
/* Port MUST be in Network Byte Order */
local.sin_port = htons(port);
// TCP socket
listen_socket = socket(AF_INET, socket_type,0);
if (listen_socket == INVALID_SOCKET){
fprintf(stderr,"Server: socket() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("Server: socket() is OK.\n");
// bind() associates a local address and port combination with the
// socket just created. This is most useful when the application is a
// server that has a well-known port that clients know about in advance.
if (bind(listen_socket, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR)
{
fprintf(stderr,"Server: bind() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("Server: bind() is OK.\n");
// So far, everything we did was applicable to TCP as well as UDP.
// However, there are certain steps that do not work when the server is
// using UDP. We cannot listen() on a UDP socket.
if (socket_type != SOCK_DGRAM)
{
if (listen(listen_socket,5) == SOCKET_ERROR)
{
fprintf(stderr,"Server: listen() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("Server: listen() is OK.\n");
}
printf("Server: %s: I'm listening and waiting connection\non port %d, protocol %s\n", argv[0], port, (socket_type == SOCK_STREAM)?"TCP":"UDP");
while(1)
{
fromlen =sizeof(from);
// accept() doesn't make sense on UDP, since we do not listen()
if (socket_type != SOCK_DGRAM)
{
msgsock = accept(listen_socket, (struct sockaddr*)&from, &fromlen);
if (msgsock == INVALID_SOCKET)
{
fprintf(stderr,"Server: accept() error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("Server: accept() is OK.\n");
printf("Server: accepted connection from %s, port %d\n", inet_ntoa(from.sin_addr), htons(from.sin_port)) ;
}
else
msgsock = listen_socket;
// In the case of SOCK_STREAM, the server can do recv() and
// send() on the accepted socket and then close it.
// However, for SOCK_DGRAM (UDP), the server will do
// recvfrom() and sendto() in a loop.
if (socket_type != SOCK_DGRAM)
retval = recv(msgsock, Buffer, sizeof(Buffer), 0);
else
{
retval = recvfrom(msgsock,Buffer, sizeof(Buffer), 0, (struct sockaddr *)&from, &fromlen);
printf("Server: Received datagram from %s\n", inet_ntoa(from.sin_addr));
}
if (retval == SOCKET_ERROR)
{
fprintf(stderr,"Server: recv() failed: error %d\n", WSAGetLastError());
closesocket(msgsock);
continue;
}
else
printf("Server: recv() is OK.\n");
if (retval == 0)
{
printf("Server: Client closed connection.\n");
closesocket(msgsock);
continue;
}
printf("Server: Received %d bytes, data \"%s\" from client\n", retval, Buffer);
printf("Server: Echoing the same data back to client...\n");
if (socket_type != SOCK_DGRAM)
retval = send(msgsock, Buffer, sizeof(Buffer), 0);
else
retval = sendto(msgsock, Buffer, sizeof(Buffer), 0, (struct sockaddr *)&from, fromlen);
if (retval == SOCKET_ERROR)
{
fprintf(stderr,"Server: send() failed: error %d\n", WSAGetLastError());
}
else
printf("Server: send() is OK.\n");
if (socket_type != SOCK_DGRAM)
{
printf("Server: I'm waiting more connection, try running the client\n");
printf("Server: program from the same computer or other computer...\n");
closesocket(msgsock);
}
else
printf("Server: UDP server looping back for more requests\n");
continue;
}
return 0;
}

Figure 1
The following is the client program.
// Client program example
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEFAULT_PORT 2007
// TCP socket type
#define DEFAULT_PROTO SOCK_STREAM
void Usage(char *progname)
{
fprintf(stderr,"Usage: %s -p [protocol] -n [server name/IP] -e [port_num] -l [iterations]\n", progname);
fprintf(stderr,"Where:\n\tprotocol is one of TCP or UDP\n");
fprintf(stderr,"\t- server is the IP address or name of server\n");
fprintf(stderr,"\t- port_num is the port to listen on\n");
fprintf(stderr,"\t- iterations is the number of loops to execute.\n");
fprintf(stderr,"\t- (-l by itself makes client run in an infinite loop,\n");
fprintf(stderr,"\t- Hit Ctrl-C to terminate it)\n");
fprintf(stderr,"\t- The defaults are TCP , localhost and 2007\n");
WSACleanup();
exit(1);
}
int main(int argc, char **argv)
{
char Buffer[128];
// default to localhost
char *server_name= "localhost";
unsigned short port = DEFAULT_PORT;
int retval, loopflag = 0;
int i, loopcount, maxloop=-1;
unsigned int addr;
int socket_type = DEFAULT_PROTO;
struct sockaddr_in server;
struct hostent *hp;
WSADATA wsaData;
SOCKET conn_socket;
if (argc >1)
{
for(i=1; i<argc; i++)
{
if ((argv[i][0] == '-') || (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 'p':
if (!stricmp(argv[i+1], "TCP"))
socket_type = SOCK_STREAM;
else if (!stricmp(argv[i+1], "UDP"))
socket_type = SOCK_DGRAM;
else
Usage(argv[0]);
i++;
break;
case 'n':
server_name = argv[++i];
break;
case 'e':
port = atoi(argv[++i]);
break;
case 'l':
loopflag =1;
if (argv[i+1]) {
if (argv[i+1][0] != '-')
maxloop = atoi(argv[i+1]);
}
else
maxloop = -1;
i++;
break;