Hi all,
I have a simple client/server setup running on my localhost that is currently set to be in a loop and to send a tcp packet containing "This is the message to send" to the server.
I'd like to have the client send the message once, wait (kind of like a keep alive) and send it again. I am noticing that it sends a bunch of packets at once and the server doesn't necessarily know what to do with it. The server echoing that the client has been sending traffic is a bit wacky.
Any ideas to get me going?
Client.c
Code:
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_TCP_PORT 7000 // Default port
#define BUFLEN 1024 // Buffer length
int main (int argc, char **argv)
{
int n, bytes_to_read;
int sd, port;
struct hostent *hp;
struct sockaddr_in server;
char *host, *bp, rbuf[BUFLEN], **pptr;
char *sbuf="This is a message to send\n\r";
char str[16];
switch(argc)
{
case 2:
host = argv[1]; // Host name
port = SERVER_TCP_PORT;
break;
case 3:
host = argv[1];
port = atoi(argv[2]); // User specified port
break;
default:
fprintf(stderr, "Usage: %s host [port]\n", argv[0]);
exit(1);
}
// Create the socket
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Cannot create socket");
exit(1);
}
bzero((char *)&server, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(port);
if ((hp = gethostbyname(host)) == NULL)
{
fprintf(stderr, "Unknown server address\n");
exit(1);
}
bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
// Connecting to the server
if (connect (sd, (struct sockaddr *)&server, sizeof(server)) == -1)
{
fprintf(stderr, "Can't connect to server\n");
perror("connect");
exit(1);
}
printf("Connected: Server Name: %s\n", hp->h_name);
pptr = hp->h_addr_list;
printf("\t\tIP Address: %s\n", inet_ntop(hp->h_addrtype, *pptr, str, sizeof(str)));
while(1){
printf("Transmiting:\n");
for(;;) {
// Transmit data through the socket
send(sd, sbuf, strlen(sbuf), 0);
sleep(12);
}
}
fflush(stdout);
close (sd);
return (0);
}
server.c
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_TCP_PORT 7000 // Default port
#define BUFLEN 80 //Buffer length
#define TRUE 1
#define LISTENQ 5
#define MAXLINE 4096
// Function Prototypes
static void SystemFatal(const char* );
int main (int argc, char **argv)
{
int i, maxi, nready, bytes_to_read, arg;
int listen_sd, new_sd, sockfd, client_len, port, maxfd, client[FD_SETSIZE];
struct sockaddr_in server, client_addr;
char *bp, buf[BUFLEN];
ssize_t n;
fd_set rset, allset;
switch(argc)
{
case 1:
port = SERVER_TCP_PORT; // Use the default port
break;
case 2:
port = atoi(argv[1]); // Get user specified port
break;
default:
fprintf(stderr, "Usage: %s [port]\n", argv[0]);
exit(1);
}
// Create a stream socket
if ((listen_sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
SystemFatal("Cannot Create Socket!");
// set SO_REUSEADDR so port can be resused imemediately after exit, i.e., after CTRL-c
arg = 1;
if (setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) == -1)
SystemFatal("setsockopt");
// Bind an address to the socket
bzero((char *)&server, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = htonl(INADDR_ANY); // Accept connections from any client
if (bind(listen_sd, (struct sockaddr *)&server, sizeof(server)) == -1)
SystemFatal("bind error");
// Listen for connections
// queue up to LISTENQ connect requests
listen(listen_sd, LISTENQ);
maxfd = listen_sd; // initialize
maxi = -1; // index into client[] array
for (i = 0; i < FD_SETSIZE; i++)
client[i] = -1; // -1 indicates available entry
FD_ZERO(&allset);
FD_SET(listen_sd, &allset);
while (TRUE)
{
rset = allset; // structure assignment
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
if (FD_ISSET(listen_sd, &rset)) // new client connection
{
client_len = sizeof(client_addr);
if ((new_sd = accept(listen_sd, (struct sockaddr *) &client_addr, &client_len)) == -1)
SystemFatal("accept error");
printf(" Remote Address: %s\n", inet_ntoa(client_addr.sin_addr));
for (i = 0; i < FD_SETSIZE; i++)
if (client[i] < 0)
{
client[i] = new_sd; // save descriptor
break;
}
if (i == FD_SETSIZE)
{
printf ("Too many clients\n");
exit(1);
}
FD_SET (new_sd, &allset); // add new descriptor to set
if (new_sd > maxfd)
maxfd = new_sd; // for select
if (i > maxi)
maxi = i; // new max index in client[] array
if (--nready <= 0)
continue; // no more readable descriptors
}
for (i = 0; i <= maxi; i++) // check all clients for data
{
if ((sockfd = client[i]) < 0)
continue;
if (FD_ISSET(sockfd, &rset))
{
for(;;) {
bp = buf;
bytes_to_read = BUFLEN;
while ((n = read(sockfd, bp, bytes_to_read)) > 0)
{
bp += n;
bytes_to_read -= n;
}
printf("%s",buf);
}
if (n == 0) // connection closed by client
{
printf(" Remote Address: %s closed connection\n", inet_ntoa(client_addr.sin_addr));
close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -1;
}
if (--nready <= 0)
break; // no more readable descriptors
}
}
}
return(0);
}
// Prints the error stored in errno and aborts the program.
static void SystemFatal(const char* message)
{
perror (message);
exit (EXIT_FAILURE);
}