Professional Documents
Culture Documents
Implementation of Quote Server Using TCP Socket
Implementation of Quote Server Using TCP Socket
Implementation of Quote Server Using TCP Socket
The example featured in this section consists of two applications: a client and a server.
The server continuously receives datagram packets over a datagram socket. Each
datagram packet received by the server indicates a client request for a quotation. When
the server receives a datagram, it replies by sending a datagram packet that contains a
one-line "quote of the moment" back to the client.
The client application in this example is fairly simple. It sends a single datagram packet
to the server indicating that the client would like to receive a quote of the moment. The
client then waits for the server to send a datagram packet in response.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <pthread.h>
#include <syslog.h>
#include <unistd.h>
typedef enum
{
false,
true
} bool;
struct message
{
long message_id;
char buffer[MAX_MESSAGE_SIZE];
};
if (pthread_attr_init(&thread_attr) != 0)
error("pthread_attr_init");
if (pthread_attr_setdetachstate(&thread_attr,
PTHREAD_CREATE_DETACHED) != 0)
error("pthread_attr_setdetachstate");
time_t now;
srand(seed);
if (close(sock_fd) == -1)
error("close");
}
if (rptr == NULL)
{ // Not successful with any address
fprintf(stderr, "Not able to bind\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result);
while (1)
{
addrlen = sizeof(struct sockaddr_storage);
// lock mutex
if ((r = pthread_mutex_lock(&client_mutex)) != 0)
{
fprintf(stderr, "Error = %d (%s)\n", r,
strerror(r));
exit(1);
}
// Unlock mutex
if ((r = pthread_mutex_unlock(&client_mutex)) != 0)
{
fprintf(stderr, "Error = %d (%s)\n", r,
strerror(r));
exit(1);
}
if (i == MAX_CLIENTS)
{
fprintf(stderr, "Can't handle more than %d clients.
Quitting\n", MAX_CLIENTS);
exit(EXIT_FAILURE);
}
if ((clients[i].accepted_sock_id = accept(sock_fd,
(struct sockaddr *)&clients[i].client, &addrlen)) == -1)
{
if (errno == EINTR)
{
// lock mutex
if ((r = pthread_mutex_lock(&client_mutex)) !=
0)
{
fprintf(stderr, "Error = %d (%s)\n", r,
strerror(r));
exit(1);
}
clients[i].is_a_client = false;
// Unlock mutex
if ((r = pthread_mutex_unlock(&client_mutex)) !=
0)
{
fprintf(stderr, "Error = %d (%s)\n", r,
strerror(r));
exit(1);
}
continue;
}
else
{
error("accept");
}
}
exit(EXIT_SUCCESS);
}
i = *((int *)arg);
// lock mutex
if ((r = pthread_mutex_lock(&client_mutex)) != 0)
{
fprintf(stderr, "Error = %d (%s)\n", r, strerror(r));
exit(1);
}
this_client = clients[i];
// Unlock mutex
if ((r = pthread_mutex_unlock(&client_mutex)) != 0)
{
fprintf(stderr, "Error = %d (%s)\n", r, strerror(r));
exit(1);
}
if ((this_client.client).ss_family == AF_INET)
{
ptr = (struct sockaddr_in *)&(this_client.client);
inet_ntop(AF_INET, &(ptr->sin_addr), str, sizeof(str));
}
else if ((this_client.client).ss_family == AF_INET6)
{
ptr1 = (struct sockaddr_in6 *)&(this_client.client);
inet_ntop(AF_INET6, &(ptr1->sin6_addr), str,
sizeof(str));
}
else
{
ptr = NULL;
fprintf(stderr, "Address family is neither AF_INET nor
AF_INET6\n");
}
if (ptr)
syslog(LOG_USER | LOG_INFO, "%s %s", "Connection from
client", str);
// lock mutex
if ((r = pthread_mutex_lock(&client_mutex)) != 0)
{
fprintf(stderr, "Error = %d (%s)\n", r,
strerror(r));
exit(1);
}
clients[i].is_a_client = false;
// Unlock mutex
if ((r = pthread_mutex_unlock(&client_mutex)) != 0)
{
fprintf(stderr, "Error = %d (%s)\n", r,
strerror(r));
exit(1);
}
break;
}
// process
switch (ntohl(recv_message.message_id))
{
case QUOTATION_PLEASE: // choose a quote
send_message.message_id =
htonl(YOUR_QUOTATION_PLEASE);
int i = rand() % num_quotes;
strcpy(send_message.buffer, quote[i]);
size_t msg_len = sizeof(long) + strlen(quote[i]) +
1;
if (send(this_client.accepted_sock_id,
&send_message, msg_len, 0) == -1)
error("send");
break;
case QUIT:
over = true;
// lock mutex
if ((r = pthread_mutex_lock(&client_mutex)) != 0)
{
fprintf(stderr, "Error = %d (%s)\n", r,
strerror(r));
exit(1);
}
clients[i].is_a_client = false;
// Unlock mutex
if ((r = pthread_mutex_unlock(&client_mutex)) != 0)
{
fprintf(stderr, "Error = %d (%s)\n", r,
strerror(r));
exit(1);
}
continue;
}
}
return (NULL);
}
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#define QUOTE_SERVER_PORT "4356"
#define QUOTATION_PLEASE 1
#define YOUR_QUOTATION_PLEASE 2
#define QUIT 0
typedef enum
false,
true
} bool;
int get_option();
struct message
long message_id;
char buffer[MAX_MESSAGE_SIZE];
};
{
if (argc != 2)
exit(EXIT_FAILURE);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int s;
exit(EXIT_FAILURE);
int sock_fd;
socklen_t length;
rptr->ai_protocol);
if (sock_fd == -1)
continue;
if (close(sock_fd) == -1)
error("close");
continue;
break;
if (rptr == NULL)
exit(EXIT_FAILURE);
}
freeaddrinfo(result);
int option;
while (1)
option = get_option();
message.message_id = htonl(option);
error("send");
if (option == QUIT)
break;
error("recv");
// display
if (ntohl(message.message_id) == YOUR_QUOTATION_PLEASE)
printf("\n%s\n\n", message.buffer);
exit(EXIT_SUCCESS);
int get_option()
int option;
while (1)
printf("Get a Quote\n\n");
printf("\tNew Quote\t1\n");
printf("\tQuit\t\t0\n\n");
scanf("%d", &option);
if (option == 0 || option == 1)
return option;
else
}
void error(char *msg)
perror(msg);
exit(1);
Output :