/******************************************************************/
/* This is a datagram socket client sample program which sends a */
/* request to the server program and receives an echo message */
/* back from the server. */
/******************************************************************/
#include <tpf/tpfeq.h>
#include <tpf/tpfio.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
qxyg(char *argv[], u_short num_arg)
{
#define NUM_PARAMETER 5
#define return_ok 0
#define return_error -1
#define no 0
#define yes 1
/***********************************************************/
/* This is the maximum message size that will be supported */
/***********************************************************/
const max_msg_size = 32 * 1024;
struct sockaddr_in client_sockaddr_in; /* Client internet addr */
struct sockaddr_in server_sockaddr_in; /* Server internet addr */
char msg = '0';
char *recv_client_message;
char *send_client_message;
int client_sock;
int msg_lost;
int msg_recv;
int msg_resend;
int msg_resyn;
int rc;
int redo_select;
int sockaddr_in_length;
int sock_list[1];
/********************/
/** Argument List **/
/********************/
int dest_ip;
int dest_port;
int num_msg;
int siz_msg;
int num_rsend;
/*******************************************************************/
/* Check the input argument list. If the number of arguments is */
/* incorrect, print out the help message. */
/*******************************************************************/
if (num_arg != NUM_PARAMETER)
{
printf("Invalid parameter(s) :\n");
printf("ztest sock client datagram block <IP addr> <port #> \
<no. of msg> <msg size> <resend>\n");
printf("ip addr - Server's IP address\n");
printf("port # - Server's port number\n");
printf("num of msg - Number of messages to be sent to \
the server \n");
printf("msg size - Size of each message to be sent\n");
printf("resend - Number of times to resend the lost message \
\n\n");
exit(0);
}
else
{
/************************************************************/
/* Extract the IP address, port number, number of messages, */
/* size of each message, and number of resends. */
/************************************************************/
dest_ip = inet_addr(argv[0]);
dest_port = atoi(argv[1]);
num_msg = atoi(argv[2]);
siz_msg = atoi(argv[3]);
num_rsend = atoi(argv[4]);
}
if (siz_msg < 0)
printf("qxyg: %d is an invalid message size\n",siz_msg);
/****************************************************************/
/* Create send/receive buffer based on user defined buffer size.*/
/****************************************************************/
send_client_message = (char *)malloc(max_msg_size);
recv_client_message = (char *)malloc(max_msg_size);
msg_resend = 0;
msg_resyn = 0;
msg_lost = 0;
sockaddr_in_length = sizeof(struct sockaddr_in);
/****************************/
/* Create a datagram socket.*/
/****************************/
client_sock = socket(AF_INET,SOCK_DGRAM,17);
if (client_sock == return_error)
{
printf("qxyg: Error in opening a datagram socket\n");
exit(0);
}
/***********************************/
/* Bind a local name to the socket.*/
/***********************************/
client_sockaddr_in.sin_family = AF_INET;
client_sockaddr_in.sin_port = 0;
client_sockaddr_in.sin_addr.s_addr = 0;
rc = bind(client_sock,(struct sockaddr *)&client_sockaddr_in,
sockaddr_in_length);
if (rc == return_error)
{
printf("qxyg: Error in binding - %d\n",sock_errno());
(void)close(client_sock);
exit(0);
}
/********************************************************/
/* Set socket to send/receive more than max_buffer_size.*/
/********************************************************/
rc = setsockopt(client_sock,SOL_SOCKET,SO_SNDBUF,
(char *)&max_msg_size,sizeof(max_msg_size));
if (rc != return_ok)
{
printf("qxyg: Error in setsockopt-SO_SNDBUF-%d\n",sock_errno());
(void)close(client_sock);
exit(0);
}
/*******************************************************************/
/* Define server's internet address which is used for sendto() and */
/* recvfrom(). */
/*******************************************************************/
server_sockaddr_in.sin_family = AF_INET;
server_sockaddr_in.sin_port = dest_port;
server_sockaddr_in.sin_addr.s_addr = dest_ip;
rc = connect(client_sock,(struct sockaddr *)&server_sockaddr_in,
sockaddr_in_length);
if (rc == return_error)
{
printf("qxyg: Error in connecting - %d\n",sock_errno());
(void)close(client_sock);
exit(0);
}
/*******************************************************************/
/* Get the client information, and print client/server data out. */
/*******************************************************************/
rc = getsockname(client_sock,(struct sockaddr *)&client_sockaddr_in,
&sockaddr_in_length);
if (rc != return_error)
{
printf("Client Information\n");
printf("--------------------------------\n");
printf("Client sock - %d\n",client_sock);
printf("Client IP address - %x\n", \
client_sockaddr_in.sin_addr.s_addr);
printf("Client port # - %d\n",client_sockaddr_in.sin_port);
printf("Server IP address - %x\n", \
server_sockaddr_in.sin_addr.s_addr);
printf("Server port # - %d\n\n",server_sockaddr_in.sin_port);
}
/**************************************************/
/* Set up the first message to send to the server.*/
/**************************************************/
(void)memset(send_client_message,msg,siz_msg);
send_client_message[siz_msg - 1] = 0;
/*******************************************************************/
/* Set up the sock_list for select() - use it for testing time out.*/
/*******************************************************************/
sock_list[0] = client_sock;
/************************************/
/* Loop until all messages are sent.*/
/************************************/
for (msg_recv = 1; msg_recv <= num_msg;)
{
/********************************/
/* Send a message to the server.*/
/********************************/
rc = send(client_sock,send_client_message,siz_msg,0);
if (rc == return_error)
{
/***********************************************/
/* If an error occurred, resend the message. */
/***********************************************/
printf("qxyg: Error in sending message to server-try again- \
%d\n",sock_errno());
msg_resend++;
}
else
{
/**********************************************************/
/* A message was successfully sent, so monitor the read. */
/* If a message arrives within 15 seconds, read it in. */
/* Otherwise, a message was lost, so send it again. */
/**********************************************************/
redo_select = yes;
for (;redo_select; )
{
rc = select(sock_list,1,0,0,15000);
if (rc >= 1)
{
/**********************************************************/
/* Read the message. If there is a problem, resend again.*/
/**********************************************************/
rc = read(client_sock,recv_client_message,max_msg_size);
if (rc == return_error)
{
printf("qxyg : Error in receiving message from server - \
%d\n", sock_errno());
msg_resend++;
}
else
{
/*********************************************************/
/* If the received message is correct, then process the */
/* message. Otherwise, throw the message out and wait */
/* for the next incoming message. */
/*********************************************************/
if (*recv_client_message == msg)
{
printf("Recv Msg %d - len = %d Source address = %x\n",
msg_recv,rc,server_sockaddr_in.sin_addr.s_addr);
msg_recv++;
msg_lost += msg_resend;
msg_resend = 0;
redo_select = no;
/***********************************/
/* Set up the next message to send.*/
/***********************************/
msg ++;
if (msg > '9')
{
msg = '0';
}
(void)memset(send_client_message,msg,siz_msg);
send_client_message[siz_msg - 1] = 0;
}
else
{
printf("qxyg: Received unexpected data. 1st character = \
%c\n", *recv_client_message);
msg_resyn++;
}
}
}
else
{
/***********************************************************/
/* If a time-out or an error in select() occurred, resend */
/* the message. */
/***********************************************************/
msg_resend++;
redo_select = no;
if (rc == 0)
printf("qxyg: Possible lost message# %d .... resend\n",
msg_recv);
else
{
printf("qxyg: error in select() - %d\n",sock_errno());
printf("Server IP address - %x\n", \
server_sockaddr_in.sin_addr.s_addr);
printf("Server port # - %d\n\n",
server_sockaddr_in.sin_port);
printf("Client terminates abnormally\n");
rc = close(client_sock);
if (rc == return_error)
{
printf("qxyg: Error in closing the socket - %d\n",
sock_errno());
}
exit(0);
}
} /* end of else (select) */
} /* end of for (;redo_select;) */
} /* end of else (sendto) */
/****************************************************************/
/* If the number of times we resent the message exceeds the */
/* resend count, terminate this program abnormally. */
/****************************************************************/
if (msg_resend >= num_rsend)
{
printf("\n");
printf("qxyg: MSG %d has been resent %d times without any \
response from the server.\n",msg_recv,msg_resend);
printf("This could be caused by busy server or unreachable IP add\
ress or port number.\n");
printf("Server IP address - %x\n", \
server_sockaddr_in.sin_addr.s_addr);
printf("Server port # - %d\n\n", \
server_sockaddr_in.sin_port);
printf("Client terminates abnormally\n");
(void)close(client_sock);
exit(0);
}
}
/*******************************************************************/
/* Print out the status. Close down socket and exit this program */
/*******************************************************************/
msg_recv--;
printf("\n");
printf("qxyg: MSG Send/Recv = %d, MSG Resyn = %d, Total MSG Lost = \
%d\n\n", msg_recv,msg_resyn,msg_lost-msg_resyn);
rc = close(client_sock);
if (rc == return_error)
{
printf("qxyg: Error in closing the socket - %d\n",sock_errno());
exit(0);
}
printf("Client terminates normally\n");
printf("Server IP address - %x\n", \
server_sockaddr_in.sin_addr.s_addr);
printf("Server port # - %d\n\n",server_sockaddr_in.sin_port);
exit(0);
}