All pastes #964759 Raw Edit

Anonymous

public text v1 · immutable
#964759 ·published 2008-03-31 15:00 UTC
rendered paste body
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

#include <linux/if.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>

#define BUFFERSIZE 512
#define MAX_THREADS 15

int threads, srvsock;
pthread_mutex_t threadlock;
void* ThreadRoutine(void* _param);

int main(int argc, char* argv[]) {
	struct sockaddr_in srv;

	if (argc < 2) {
	  printf("usage: tcpsrv6 <portnumber>\n");
	  exit(1);
	}
	printf ("Multi-Threaded echo server started.\n");

	if ((srvsock = socket (AF_INET, SOCK_STREAM, 0)) == -1) {
		perror ("creating socket");
		exit (1);
	}

	memset (&srv, 0, sizeof (struct sockaddr_in));	
	srv.sin_family = AF_INET;
	srv.sin_port = htons(atoi(argv[1]));
	srv.sin_addr.s_addr = htonl(INADDR_ANY);

	if (bind (srvsock, (struct sockaddr *)&srv, sizeof(srv)) != 0) {
		perror ("bind addr");
		exit (1);
	}

	printf("Listening...\n");

	listen(srvsock, 10);
	while (threads < MAX_THREADS) {
		pthread_t thread;
		if (pthread_create(&thread, NULL, ThreadRoutine, (void*)NULL) == -1) { perror("pthread_create"); exit(1); }
		if (pthread_mutex_lock(&threadlock) != 0) { perror("mutex lock error"); exit(1); }
		threads++; /* increase threads accepting */
		if (pthread_mutex_unlock(&threadlock) != 0) { perror("mutex unlock error"); exit(1); }
	}
	while (1) {
		if (threads < MAX_THREADS) {
			pthread_t thread;
			if (pthread_create(&thread, NULL, ThreadRoutine, (void*)NULL) == -1) { perror("pthread_create"); exit(1); }
			if (pthread_mutex_lock(&threadlock) != 0) { perror("mutex lock error"); exit(1); }
			threads++; /* increase threads accepting */
			if (pthread_mutex_unlock(&threadlock) != 0) { perror("mutex unlock error"); exit(1); }
		}
		sleep(1);		
	}
	close (srvsock);
	return 0;
}

void* ThreadRoutine(void* _param) {
	char buffer[BUFFERSIZE];			/* buffer met lengte van BUFFERSIZE */
	int i;
	struct sockaddr_in cli;
	size_t cli_size = sizeof(cli);			/* Grootte van cli om later naar het adres te refereren */

	printf("New accept thread\n");

	while (1) {
		if ((i = accept(srvsock, (struct sockaddr *)&cli, &cli_size)) > 0) {
			printf("Connected to %s (socket: %i)\n", inet_ntoa(cli.sin_addr), i);
			if (pthread_mutex_lock(&threadlock) != 0) { perror("mutex lock error"); exit(1); }
			threads--;
			if (pthread_mutex_unlock(&threadlock) != 0) { perror("mutex unlock error"); exit(1); }
			while(1) {
				if (recv(i, buffer, BUFFERSIZE, 0) > 0 && send(i, buffer, BUFFERSIZE, 0) > 0) {
					buffer[strlen(buffer)-1] = '\0';
					printf("Returned %s to sender (%s) (socket: %i).\n", buffer, inet_ntoa(cli.sin_addr), i);
				}
				else {
					close(i);
					printf("Closing thread (socket: %i, ip: %s).\n", i, inet_ntoa(cli.sin_addr));
					pthread_exit(NULL);
				}
			}
		}
		else { printf("Accept error\n"); }
	}
}