I started working on a select server and am encountering some issues.
Heres the problem; I ran an strace on my select server and i fired it up and it creates the socket, binds, listens, and select waits for input. When you connect the client, select adds a file descriptor to its fd_set. Then waits for input with read. SO i type a message from the client to the server, "Hey man hows it going? The server takes the input(22 characters), and write prints the message twice(44 characters). Then i am left with a hanging server. Any ideas?

also, if you manually exit from the server it will close the server out but it will prompt the client to enter a message 2 more times then exit by tself.

if you manually exit from the client, the server will print the eror handle i have for if read is == 0. then exits by itself.

Hope someone can help!

here is the server code

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>

int read_from_client(int file_des) {
	char buffer[1024];
	int read_var;

        int i = sizeof(buffer)-1; if(i > 0) bzero(buffer, sizeof(buffer));
	read_var = read(file_des, buffer, sizeof(buffer)-1);

	if(read_var < 0) {
		fprintf(stderr, "READ() error \n");
	} else if(read_var == 0) {
		 fprintf(stderr, "Exiting\n");
	else {
		fprintf (stdout, "Server: got message: %s\n", buffer);
                return 0;


int main(int argc, char *argv[]) {
	int sockfd, newsockfd, portno, i;
	socklen_t clilen;
	struct sockaddr_in serv_addr, cli_addr;
	fd_set read_fds;
	int yes = 1;

	if (argc < 2) fprintf(stderr, "No port provided ");

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) {
		fprintf(stderr, "Error creating socket  SOCKET()\n");

	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
		fprintf(stderr, "Address already in use  SETSOCKOPT()\n");

	bzero((char *) &serv_addr, sizeof(serv_addr));
	portno = atoi(argv[1]);
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port = htons(portno);

	if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
		fprintf(stderr, "Error binding to socket  BIND()\n");

	listen(sockfd, 10);
        clilen = sizeof(cli_addr);

	FD_SET(sockfd, &read_fds);

	for( ; ; ) { /*1rst for loop*/
		i = select(FD_SETSIZE, &read_fds, NULL, NULL, NULL); 
		if (i < 0) { /*1rst if statement*/
			fprintf(stderr, "Select server error  SELECT() %s\n", strerror(errno));
		for (i = 0; i < 20; ++i) {  // should be high enough
			if(FD_ISSET(i, &read_fds)) {
				if(i == sockfd) {
					newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
					if (newsockfd < 0) {
						fprintf(stderr, "Error accepting new connection  ACCEPT() %s\n", strerror(errno));
					FD_SET(newsockfd, &read_fds);
				} else {
					if(read_from_client (i) < 0) {
						FD_CLR(i, &read_fds);



Recommended Answers

All 2 Replies

i solved the issue. but have a question. i found that if i do not add a newline char to the end of fprintf to stdout, it will hang. But if i add the \n it works...

int read_from_client(int file_des) {
	char buffer[1024];
	int read_var;

        buffer[read_var] = 0;
	read_var = read(file_des, buffer, sizeof(buffer)-1);//Using strlen(buffer) causes read to automatically return 0.

	if(read_var < 0) 
        printf("READ(-1) %s\n", strerror(errno));
		else if(read_var == 0) 
		printf("READ(0) %s\n", strerror(errno));
			fprintf(stdout, "Client: %s\n", buffer);//Needs '\n' in order to print client message in the buffer
			//getchar(); Causes write to == 0.
        	        return 0;
	return 0;

Why is that?

i found that if i do not add a newline char to the end of fprintf to stdout, it will hang. But if i add the \n it works...

fprintf doesn't print the message until the output buffer is full. To make the prompt to be displayed immediately, you should include '\n' or use 'fflush' like this:

fflush(stdout);//flushes the output buffer

see here(also see the footnote).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.