Code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
static char *host = "localhost";
static int port = 1234;
int serverfd;
int bytes_in_buf = 0;
char buf[200];
static void connect_to_server();
static void do_something();
char *memnewline(char *p, int size);
static void clear_buf();
static fd_set fdlist;
static void do_handle_setup();
int main(int argc, char **argv) {
connect_to_server();
do_handle_setup();
clear_buf();
while (1) {
do_something();
}
return 0;
}
static void clear_buf() {
memset(buf, '\0', sizeof(buf));
bytes_in_buf = 0;
}
static void connect_to_server() {
struct hostent *hp;
struct sockaddr_in r;
if ((hp = gethostbyname(host)) == NULL) {
fprintf(stderr, "%s: no such host\n", host);
exit(1);
}
if (hp->h_addr_list[0] == NULL || hp->h_addrtype != AF_INET) {
fprintf(stderr, "%s: not an internet protocol host name\n", host);
exit(1);
}
if ((serverfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
memset((char *) &r, '\0', sizeof r);
r.sin_family = AF_INET;
memcpy((char *) &r.sin_addr, hp->h_addr_list[0], hp->h_length);
r.sin_port = htons(port);
if (connect(serverfd, (struct sockaddr *) &r, sizeof r) < 0) {
perror("connect");
exit(1);
}
int n;
while (memnewline(buf, bytes_in_buf) == NULL) {
if ((n = read(serverfd,
buf + bytes_in_buf,
sizeof(buf) - bytes_in_buf)) == -1) {
perror("read");
exit(1);
}
bytes_in_buf += n;
}
// Establish file descriptor lists for stdin and server reading.
FD_ZERO(&fdlist);
FD_SET(serverfd, &fdlist);
FD_SET(fileno(stdin), &fdlist);
}
static void send_to_server(char *data) {
if (write(serverfd, data, strlen(data)) != strlen(data)) {
perror("write");
exit(1);
}
}
static void do_handle_setup() {
printf("%s\n", "Give handle:\n");
fgets(buf, sizeof(buf), stdin);
send_to_server(buf);
}
static void do_something() {
char *q;
if ((q = memnewline(buf, bytes_in_buf))) {
printf("server: %s\n", buf);
clear_buf();
} else {
printf("select\n");
switch (select(serverfd + 1, &fdlist, NULL, NULL, NULL)) {
case 0:
break;
case -1:
perror("select");
break;
default:
if (FD_ISSET(fileno(stdin), &fdlist)) {
if (! fgets(buf, sizeof buf, stdin)) {
if (ferror(stdin)) {
perror("stdin");
exit(1);
}
}
} else if (FD_ISSET(serverfd, &fdlist)) {
int n;
if ((n = read(serverfd,
buf + bytes_in_buf,
sizeof(buf) - bytes_in_buf)) == -1) {
perror("read");
exit(1);
}
bytes_in_buf += n;
}
}
}
}
char *memnewline(char *p, int size) /* finds \r _or_ \n */
/* This is like min(memchr(p, '\r'), memchr(p, '\n')) */
/* It is named after memchr(). There's no memcspn(). */
{
for (; size > 0; p++, size--)
if (*p == '\r' || *p == '\n')
return(p);
return(NULL);
}
Basically the memnewline() function is used to determine when a \r\n is found then the buf is cleared.