호타리 2025. 6. 18. 16:19

2025.06.18

 

01.thread_create.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <unistd.h>
#include <sys/syscall.h>

void *thread_function(void *arg);

int main() {
	int status;
	pthread_t tid;
	pthread_attr_t attr;
	void *thread_result;
	int i;
	

	pthread_attr_init(&attr);
	status = pthread_create(&tid, &attr, thread_function, "hello thread");
	// status = pthread_create(&tid, NULL, thread_function,(void *) NULL);
	if(status !=0){
		perror("pthread_create");
		exit(1);
	}
	printf("Created Thread ID = %u\n", (unsigned int)tid);
	
	for(i=1; i<=5; i++){
		printf("Parent thread %d!!\n", i);
		sleep(1);
	}
	return 0;
}

void *thread_function(void *arg){
	int i;
	pid_t tpid, pid;
	
	pthread_t thread_id;
	thread_id = pthread_self();
	printf("Thread ID: %u\n", (unsigned int)thread_id);

	for(i=1; i<=10; i++){
		printf("\t\tChild thread[%d] - %s\n", i, (char *)arg);
		sleep(1);
	}
	return NULL;
}

 

02.thread_join.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <stdint.h>

//#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <unistd.h>
#include <sys/syscall.h>

void *thread_function(void *arg);

int main() {
	int status;
	pthread_t tid;
	void *return_value;
	int i;

	
	status = pthread_create(&tid, NULL, thread_function, "hello thread\n");
	if(status !=0){
		perror("pthread_create");
		exit(1);
	}
	
	for(i=1; i<=5; i++){
		printf("Parent thread %d!!\n", i);
		sleep(1);
	}

	//
	status = pthread_join(tid, &return_value);
	if(status != 0){
		perror("pthread_join");
		exit(1);
	}
	printf("Thread joined, it returned %s\n", (char *)return_value); 
	// printf("Thread joined, it returned %ld\n", (uintptr_t)return_value); 
	
	return 0;
}

void *thread_function(void *arg){
	int i;
	pid_t * tpid;
	pthread_t * thread_id;
	
	tpid=malloc(sizeof(pid_t));
	thread_id=malloc(sizeof(pthread_t));

	*tpid = syscall(SYS_gettid);
	printf("Thread LWP: %d, Thread PID: %d\n", *tpid, getpid());
	
	*thread_id = pthread_self();
	printf("Thread ID: %lu\n", *thread_id);
	
	for(i=1; i<=10; i++){
		printf("\t\tChild thread %d\n", i);
		sleep(1);
	}
	// pthread_exit("Good Bye");
	// return (void *)1;
	pthread_exit((void *)0);
}

 

03.thread_exit.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

//#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <unistd.h>
#include <string.h>
#include <sys/syscall.h>

void *thread_function(void *arg);

int main() {
	int status, i;
	pthread_t tid;
	void *thread_result;
	void * ret;

	status = pthread_create(&tid, NULL, thread_function, "hello thread");
	if(status !=0){
		perror("pthread_create");
		exit(1);
	}
	
	sleep(1);
	pthread_cancel(tid);
	pthread_join(tid, &ret);
	printf("RET = %ld\n", (intptr_t)ret);
	return 0;
}

void *thread_function(void *arg){
	int i;
	pid_t tpid, pid;
	int ret, unused;
#if 0
	ret = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &unused);
#else
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
#endif

	for(int i=1; i<=10; i++){
		printf("\tChild thread %d\n", i);
		for(int k=0; k<300000000; k++) {}
		if(i==7){
			pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &unused);
		}
	}
	return (void *) 5;
}

 

01.multi-thread.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void *isprime(void *arg);
void *progress(void *arg);

int main(int argc, char *argv[]){
  long long num1;
  long long num2;
  pthread_t tid1, tid2, tid3;
  pthread_attr_t attr;
  if (argc != 3) {
    fprintf(stderr, "Please supply two numbers.\n" "Example: %s 9 7\n", argv[0]);
    return 1;
  }
  num1 = atoll(argv[1]);
  num2 = atoll(argv[2]);
  
  pthread_attr_init(&attr);
  
  pthread_create(&tid3, &attr, progress, NULL);
  pthread_detach(tid3);
  
  pthread_create(&tid1, &attr, isprime, &num1);
  pthread_create(&tid2, &attr, isprime, &num2);
  
  pthread_join(tid1, NULL);
  pthread_join(tid2, NULL);
  
  pthread_attr_destroy(&attr);
  if (pthread_cancel(tid3) != 0)
     fprintf(stderr, "Couldn't cancel progress thread\n");
  printf("Done!\n");
	sleep(3);
  return 0;
}

void *isprime(void *arg){
   long long int number = *((long long*)arg);
   long long int j;
   int prime = 1;
    
   for(j=2; j<number; j++) {
      if(number%j == 0){
         prime = 0;
      }
   }
   if(prime == 1){
      printf("\n%lld is a prime number\n", number);
      return NULL;
   }else{
      printf("\n%lld is not a prime number\n", number);
      return NULL;
   }
}

void *progress(void *arg){
   while(1) {
      sleep(1);
      printf(".");
      fflush(stdout);
   }
   return NULL;
}

 

02.thread-return.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdint.h>

void *isprime(void *arg);
void *progress(void *arg);

int main(int argc, char *argv[]){
   long long num1;
   long long num2;
   pthread_t tid1;
   pthread_t tid2;
   pthread_t tid3;
   void *result1;
   void *result2;
   if (argc != 3){
      fprintf(stderr, "Please supply two numbers.\n" "Example: %s 9 7\n", argv[0]);
      return 1;
   }
   num1 = atoll(argv[1]);
   num2 = atoll(argv[2]);
   
   pthread_create(&tid3, NULL, progress, NULL);  
   pthread_detach(tid3);
   pthread_create(&tid1, NULL, isprime, &num1);
   pthread_create(&tid2, NULL, isprime, &num2);

   pthread_join(tid1, &result1);
   if ((uintptr_t)result1 == 1)
      printf("\n%lld is a prime number\n", num1);
   else
      printf("\n%lld is not a prime number\n", num1);
         
   pthread_join(tid2, &result2);   
   if ((uintptr_t)result2 == 1)
      printf("\n%lld is a prime number\n", num2);
   else
      printf("\n%lld is not a prime number\n", num2);
   
   if ( pthread_cancel(tid3) != 0 )
      fprintf(stderr, "Couldn't cancel progress thread\n");
   return 0;
}

void *isprime(void *arg) {
   long long int number = *((long long*)arg);
   long long int j;
   int prime = 1;
    
   for(j=2; j<number; j++){
      if(number%j == 0)
         prime = 0;
   }
   if(prime == 1)
      return (void*)1;
   else
      return (void*)0;
}

void *progress(void *arg){
   while(1){
      sleep(1);
      printf(".");
      fflush(stdout);
   }
   return NULL;
}

 

01.endian_conv.c

#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
	unsigned char *addr;
	unsigned int host_addr;
	unsigned int net_addr;
	
	struct sockaddr_in sock_addr;

	host_addr=0xc0a83865;
	printf("LIEELE ENDIAN = %#x\n", host_addr);
	addr = (unsigned char *)&host_addr;
	printf("MEM-ADDR = %p \t\t%#x\n", addr, *addr++);
	printf("MEM-ADDR = %p \t\t%#x\n", addr, *addr++);
	printf("MEM-ADDR = %p \t\t%#x\n", addr, *addr++);
	printf("MEM-ADDR = %p \t\t%#x\n", addr, *addr++);
	
	sock_addr.sin_addr.s_addr=host_addr;
	printf("LITTLE ENDIAN IP_ADDR = %s\n\n", inet_ntoa(sock_addr.sin_addr));
	
	net_addr=htonl(host_addr);
	printf("BIG ENDIAN = %#x\n", net_addr);
	addr = (unsigned char *)&net_addr;
	printf("MEM-ADDR = %p \t\t%#x\n", addr, *addr++);
	printf("MEM-ADDR = %p \t\t%#x\n", addr, *addr++);
	printf("MEM-ADDR = %p \t\t%#x\n", addr, *addr++);
	printf("MEM-ADDR = %p \t\t%#x\n", addr, *addr++);
	
	sock_addr.sin_addr.s_addr=net_addr;	
	printf("BIG ENDIAN IP_ADDR = %s\n", inet_ntoa(sock_addr.sin_addr));
	return 0;
}

 

02.ip-address.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>

int main(int argc, char * argv[]){
	in_addr_t ipaddr;
	struct sockaddr_in sock_addr; 
	struct in_addr sip_addr;
	unsigned char *addr;
	
	ipaddr=inet_network(argv[1]); 	// host_addr=inet_network("192.168.60.100");
	printf("inet_network() = %#x\n", ipaddr);
	addr = (unsigned char *)&ipaddr;
	printf("MEM-ADDR = %p ", addr);
	printf(" --> %#x ", *addr);
	printf("\t%#x %#x %#x %#x\n", *addr, *addr++, *addr++, *addr++);
	
	sock_addr.sin_addr.s_addr=inet_addr(argv[1]);
	ipaddr=sock_addr.sin_addr.s_addr;
	printf("inet_addr() = %#x\n", ipaddr);
	addr = (unsigned char *)&ipaddr;
	printf("MEM-ADDR = %p ", addr);
	printf(" --> %#x ", *addr);
	printf("\t%#x %#x %#x %#x\n", *addr, *addr++, *addr++, *addr++);
	
	inet_aton(argv[1], &sip_addr);
	printf("inet_aton() = %#x\n", sip_addr.s_addr);
	ipaddr=sip_addr.s_addr;
	addr = (unsigned char *)&ipaddr;
	printf("MEM-ADDR = %p ", addr);
	printf(" --> %#x ", *addr);
	printf("\t%#x %#x %#x %#x\n", *addr, *addr++, *addr++, *addr++);
	
	
	inet_pton(AF_INET, argv[1], &(sock_addr.sin_addr));
	printf("inet_pton() = %#x \n", sock_addr.sin_addr.s_addr);
	
	addr=inet_ntoa(sock_addr.sin_addr);
	printf("inet_ntoa() = %s\n", addr);
	return 0;
}

 

01.tcp_client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc, char* argv[]){
	int sockfd;
	struct sockaddr_in sockaddr;
	char message[500];
	int bytes_recv;
	socklen_t len;
	
	if(argc!=3){
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}
	
	sockfd=socket(PF_INET, SOCK_STREAM, 0);
	if(sockfd == -1){
		perror("sockfdet() error!!");
		exit(1);
	}
	
	memset(&sockaddr, 0, sizeof(sockaddr));
	sockaddr.sin_family=AF_INET;
	sockaddr.sin_addr.s_addr=inet_addr(argv[1]);
	sockaddr.sin_port=htons(atoi(argv[2]));
		
	if(connect(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr))==-1){
		perror("connect() error!!");
		exit(1);
	}

#if 1			//It is to see the peer information in terms of name and port #
	len = sizeof(sockaddr);
	getpeername(sockfd, (struct sockaddr*)&sockaddr, &len);
	printf("Peer IP address: %s\n", inet_ntoa(sockaddr.sin_addr));
	printf("Peer port      : %d\n", ntohs(sockaddr.sin_port));
#endif
	bzero(&message, sizeof(message));
	bytes_recv=recv(sockfd, message, sizeof(message), 0);
	//bytes_recv=read(sockfd, message, sizeof(message));
	if(bytes_recv==-1){
		perror("recv() error!!");
		exit(1);
	}
	printf("Message from server: %s (%d)\n", message, bytes_recv); 
	
	printf("Press Enter to close the socket!!!");
	getchar();

	close(sockfd);
	return 0;
}

02.tcp_server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int argc, char *argv[]){
	int server_sfd;
	int client_sfd;

	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t sock_size;
	
	int bytes_sent;
	char message[]="Welcome to Linux Network Programming!";
	int yes = 1;
	
	if(argc!=2){
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
	
	server_sfd=socket(PF_INET, SOCK_STREAM, 0);
	if(server_sfd == -1){
		perror("socket() error!!");
		exit(1);
	}

#if 1
	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
		perror("setsockopt() error!!");
		exit(1);
	}
#endif
	
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(atoi(argv[1]));

	if(bind(server_sfd, (struct sockaddr*) &server_addr, sizeof(server_addr))==-1 ){
		perror("bind() error!!");
		exit(1);
	}
	
	if(listen(server_sfd, 10)==-1){
		perror("listen() error!!");
		exit(1);
	}
	
	sock_size=sizeof(client_addr);  
	client_sfd=accept(server_sfd, (struct sockaddr*)&client_addr,&sock_size);
	printf("Connected to the client port --> %d\n", htons(client_addr.sin_port));
	if(client_sfd==-1){
		perror("accept() error!!");
		exit(1);
	}
	
	bytes_sent = send(client_sfd, message, strlen(message), 0);
	//bytes_sent=write(client_sfd, message, sizeof(message));
	printf("bytes_sent : %d\n", bytes_sent);

	printf("Press Enter to close the socket!!!");
	getchar();

	close(client_sfd);	
	close(server_sfd);
	return 0;
}

 

01-1.tcp_client_close.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>

/*
	This example requites to work with 02-1.tcp_server_close.c to see if what happens
	when server close the socket while waiting for recv().
	To test it, server keeps hiting the "Enter" until the socket is closed
*/

int main(int argc, char* argv[]) {
	int sockfd;
	struct sockaddr_in sockaddr;
	char message[500];
	int bytes_recv;
	
	if(argc!=3) {
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}
	
	sockfd=socket(PF_INET, SOCK_STREAM, 0);
	if(sockfd == -1) {
		perror("socket() error!!");
		exit(1);
	}
	
	memset(&sockaddr, 0, sizeof(sockaddr));
	sockaddr.sin_family=AF_INET;
	sockaddr.sin_addr.s_addr=inet_addr(argv[1]);
	sockaddr.sin_port=htons(atoi(argv[2]));
		
	if(connect(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr))==-1) {
		perror("connect() error!!");
		exit(1);
	}
	for(int i=0; i<5; i++) {
		bzero(&message, sizeof(message));
		bytes_recv=recv(sockfd, message, sizeof(message), 0);
	//bytes_recv=read(sockfd, message, sizeof(message));
		if(bytes_recv==-1)	{
			perror("recv() error!!");
			exit(1);
	}
	if(bytes_recv == 0){
		printf("socket is closed by the other end!!!\n");
		break;
	}
		printf("Message from server: %s \n", message); 
	}
	
	close(sockfd);
	return 0;
}

/*
* while waiting for new message using recv, client may be able to detect 
* the lost of connection when a server close the socket.
*/

 

02-1.tcp_server_close.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

/*
	This example may work together with 01.tcp_client.c 
	and the client is waiting for server to close the socket fibytes_sent
*/

int main(int argc, char *argv[]) {
	int server_sfd;
	int client_sfd;

	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t client_addr_size;
	
	int bytes_sent;

	char message[]="Welcome to Linux Network Programming!";

	int yes = 1;
	
	if(argc!=2) {
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
	
	server_sfd=socket(PF_INET, SOCK_STREAM, 0);
	if(server_sfd == -1) {
		perror("socket() error!!");
		exit(1);
	}

#if 1
	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
		perror("setsockopt() error!!");
		exit(1);
	}
#endif
	
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(atoi(argv[1]));

	if(bind(server_sfd, (struct sockaddr*) &server_addr, sizeof(server_addr))==-1 )	{
		perror("bind() error!!");
		exit(1);
	}
	
	if(listen(server_sfd, 5)==-1)	{
		perror("listen() error!!");
		exit(1);
	}
	
	client_addr_size=sizeof(client_addr);  
	client_sfd=accept(server_sfd, (struct sockaddr*)&client_addr,&client_addr_size);
	printf("Connected to the client port --> %d\n", htons(client_addr.sin_port));
	if(client_sfd==-1) {
		perror("accept() error!!");
		exit(1);
	}
	
	bytes_sent = send(client_sfd, message, strlen(message), 0);
	printf("bytes_sent : %d\n", bytes_sent);
	//write(client_sfd, message, sizeof(message));
	if(bytes_sent == -1){
		printf("Socket is closed by the other end!!!\n");
		close(client_sfd);	
		close(server_sfd);
	}
	
	printf("Enter to send...");
	getchar();
	
	bytes_sent = send(client_sfd, message, sizeof(message), 0);
	printf("bytes_sent1 : %d\n", bytes_sent);
	//write(client_sfd, message, sizeof(message));
	if(bytes_sent == 0){
		printf("Socket1 is closed by the other end!!!\n");
		close(client_sfd);	
		close(server_sfd);
	}

	printf("Enter to send...");
	getchar();

	bytes_sent = send(client_sfd, message, sizeof(message), 0);
	printf("bytes_sent2 : %d\n", bytes_sent);
	//send() doesn't return 0 when the socket is not available due to close
	if(bytes_sent == -1){
		printf("Socket2 is closed by the other end!!!\n");
		close(client_sfd);	
		close(server_sfd);
	}
	
#if 1
	printf("Enter to close the socket!!!");
	getchar();
#endif
	close(client_sfd);	
	close(server_sfd);
	
	return 0;
}

 

02-1.tcp_server_sigpipe.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/wait.h>

/*
	This example is to demonstrate how to detect lost of the socket connection 
	by using signal SIGPIPE which will be sent to the application when send() is failed 
	when socket is closed by the client
*/

int server_sfd;
int client_sfd;

void handler(int signo) {
	int ret;
	int status;
	
	printf("Server detected the connection lost by receiving signal(%d)\n", signo);
	close(client_sfd);	
	close(server_sfd);	
	printf("Sockets closed -----\n");
	
}

int main(int argc, char *argv[]) {
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t sock_size;

	char message[]="Welcome to Linux Network Programming!";

	int yes = 1;
	
	if(argc!=2) {
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
	
	signal(SIGPIPE, handler);
	
	server_sfd=socket(PF_INET, SOCK_STREAM, 0);
	if(server_sfd == -1){
		perror("socket() error!!");
		exit(1);
	}

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
		perror("setsockopt() error!!");
		exit(1);
	}
	
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(atoi(argv[1]));

	if(bind(server_sfd, (struct sockaddr*) &server_addr, sizeof(server_addr))==-1 ) {
		perror("bind() error!!");
		exit(1);
	}
	
	if(listen(server_sfd, 5)==-1) {
		perror("listen() error!!");
		exit(1);
	}
	
	sock_size=sizeof(client_addr);  
	client_sfd=accept(server_sfd, (struct sockaddr*)&client_addr,&sock_size);
	printf("Connected to the client port --> %d\n", htons(client_addr.sin_port));
	if(client_sfd==-1){
		perror("accept() error!!");
		exit(1);
	}
	
	for(int i=0; i<10; i++){
		send(client_sfd, message, sizeof(message), 0);
		//write(client_sfd, message, sizeof(message));
		sleep(1);
	}
	
	return 0;
}

/*
* When server is tring to send a packet and the connection is closed by client,
* the kernel may detect it and deliver a signal of SIGPIPE to the server process. 
*/

 

01.hello_client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int argc, char *argv[]){
	int sockfd;
	struct sockaddr_in sockaddr;
	socklen_t sock_size;
	int bytes_sent;

	char message1[]="Hello world ";
	char message2[]="Good morning ";
	char message3[]="I am a few good man";

	if(argc!=3) {
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}
	
	sockfd=socket(PF_INET, SOCK_STREAM, 0);
	if(sockfd == -1) {
		perror("socket() error!!");
		exit(1);
	}

	memset(&sockaddr, 0, sizeof(sockaddr));
	sockaddr.sin_family=AF_INET;
	sockaddr.sin_addr.s_addr=inet_addr(argv[1]);
	sockaddr.sin_port=htons(atoi(argv[2]));

	if(connect(sockfd, (struct sockaddr*)&sockaddr, sizeof(sockaddr))==-1) {
		perror("connect() error!!");
		exit(1);
	}
	
	bytes_sent = send(sockfd, message1, strlen(message1), 0);
	printf("bytes_sent1 = %d\n", bytes_sent);
	bytes_sent = send(sockfd, message2, strlen(message2), 0);
	printf("bytes_sent2 = %d\n", bytes_sent);
	bytes_sent = send(sockfd, message3, strlen(message3), 0);
	printf("bytes_sent3 = %d\n", bytes_sent);

	close(sockfd);
	return 0;
}

 

02.hello_server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int argc, char* argv[]){
	int server_sfd, client_sfd;
	struct sockaddr_in server_addr, client_addr;
	socklen_t sock_size;
	char message[128];					//should be big enough to place the entire tcp_rx_buf
	int bytes_recv=0, idx=0;
	char t_rxbuf[20];					//should be enough to place the receive() size
	int yes = 1;
	
	if(argc!=2){
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
	
	server_sfd=socket(PF_INET, SOCK_STREAM, 0);
	if(server_sfd == -1)	{
		perror("socket() error!!");
		exit(1);
	}

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
		perror("setsockopt() error!!");
		exit(1);
	}

	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(atoi(argv[1]));
	
	if(bind(server_sfd, (struct sockaddr*) &server_addr, sizeof(server_addr))==-1 ) { 
		perror("bind() error!!");
		exit(1);
	}
	
	if(listen(server_sfd, 5)==-1) {
		perror("listen() error!!");
		exit(1);
	}
	
	sock_size=sizeof(client_addr);  
	client_sfd=accept(server_sfd, (struct sockaddr*)&client_addr,&sock_size);
	if(client_sfd==-1) {
		perror("accept() error!!");
		exit(1);
	}

	bzero(&message, sizeof(message));
#if 0
	bytes_recv=recv(client_sfd, message, sizeof(message), 0);
#else
	while( bytes_recv=recv(client_sfd, &message[idx], 8, 0) ) {
		printf("Receiving index %d(%d)\n", idx, bytes_recv);
		if(bytes_recv == 0) {
			break;
		} else {
			memset(t_rxbuf, 0, sizeof(t_rxbuf));
			strncpy(t_rxbuf, &message[idx], bytes_recv);			
			printf("recv ok(%d:%s)\n", idx, t_rxbuf);
			idx += bytes_recv;
		}
		bytes_recv += bytes_recv;
	}
#endif
	
	printf("Message from %s: %s\n", inet_ntoa(client_addr.sin_addr), message);  
	close(client_sfd);
	close(server_sfd);
	return 0;
}

 

01.mytcpclient.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int argc, char *argv[]){
	int sockfd, bytes_recv; 
	struct sockaddr_in sockaddr;
	char tx_buf[128], rx_buf[128];
	int i;

	if(argc != 2){
		fprintf(stderr, "usage : client serverip \n");
		exit(1);
	}

	//socket open
	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		perror("socket() error");
		exit(1);
	}

	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htons(10000);
	sockaddr.sin_addr.s_addr = inet_addr(argv[1]);    
	/*  sockaddr.sin_addr.s_addr = inet_addr("70.12.117.90");  */
	memset(&(sockaddr.sin_zero), '\0',8);

	printf("[ %s ]\n", inet_ntoa(sockaddr.sin_addr));

	//connection request to server
	if(connect(sockfd, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr)) == -1){
		perror("connect() error");
		exit(1);
	}
	
	for(i=1; i<=10; i++) {
		memset(tx_buf, 0, sizeof(tx_buf));
		memset(rx_buf, 0, sizeof(rx_buf));
		sprintf(tx_buf, "Hello_%d server(from %d)!!\n", i, getpid());
		//messge send to server
		if(send(sockfd, tx_buf, strlen(tx_buf)+1, 0) == -1) 
			perror("send");
		//message rx wait from server
		if((bytes_recv = recv(sockfd, rx_buf, sizeof(rx_buf), 0)) == -1){
			perror("recv");
			exit(1);
		}
		printf("----->Client Received : %s", rx_buf);
		sleep((getpid()+i)%5);
	}
	//close socket
	close(sockfd);
	return 0;
}

 

02.mytcpserver_fork_wrong.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>   
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>   
#include <sys/wait.h>

int main(void) {
	int server_sfd, client_sfd, bytes_recv;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sock_size;
	int yes = 1;
	char tx_buf[128], rx_buf[128];
	int i;

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

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
		perror("setsockopt() error");
		exit(1);
	}
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(10000); //server port number setting
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	memset(&(server_addr.sin_zero), '\0', 8);

	//server ip & port number setting
	if(bind(server_sfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
		perror("bind() error");
		exit(1);
	}

	//client backlog setting
	if(listen(server_sfd, 5) == -1) {
		perror("listen() error");
		exit(1);
	}

	while(1) {
		sock_size = sizeof(struct sockaddr_in);

		//wait for client request
		if((client_sfd = accept(server_sfd, (struct sockaddr *)&client_addr, &sock_size)) == -1) {
			perror("accept() error");
			continue;
		}

		printf("server : got connection from %s \n", inet_ntoa(client_addr.sin_addr));

		if(!fork()){
			close(server_sfd);
			for(i=1; ; i++) {
				memset(tx_buf, 0, sizeof(tx_buf));
				memset(rx_buf, 0, sizeof(rx_buf));
				//wait for rx data from client	
				if((bytes_recv = recv(client_sfd, rx_buf, sizeof(rx_buf), 0)) == -1){
					perror("recv");
					exit(1);
				}
				if(bytes_recv == 0) 
					break;	
				printf("Server Rx(%d) : %s", getpid(), rx_buf);
				sprintf(tx_buf, "Hi_%d, client(from %s)~~\n", i, inet_ntoa(server_addr.sin_addr));
				//send data to client
				if(send(client_sfd, tx_buf, strlen(tx_buf)+1, 0) == -1) perror("send");	
			}
			printf("Server(%d): Client Connection Socket Closed!!\n", getpid());
			//close client socket connection		
			close(client_sfd);
			exit(0);
		}
		close(client_sfd);	//parent close the client socket as they are being servered by child
		waitpid(-1, NULL, WNOHANG);
	}
	return 0;
}

 

 

02-1.mytcpserver_fork_well.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>   
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>   
#include <sys/wait.h>

/* 
	Original example code has Zombie process left behind.
	In order to get rid of those Zombie process, it is mandatory, in this example, 
	to hand signal SIGCHLD which would be received when a child process is dead.
*/

void handler(int signo) {
	int ret;
	int status;
	
	printf("Signal Handler starts -----\n");
	ret = waitpid(-1, &status, WNOHANG);
	if(ret == 0) {
		printf("PID %d child process is dead\n", ret);
		// break;
	}
	if(ret == -1 && errno == ECHILD) {
		printf("No Child --\n");
		// break;
	}
	if(ret == -1) {
		perror("child waitpid");
		abort();
	}
	printf("PID %d child process is dead\n", ret);
	printf("Signal Handler ends -----\n");
}

int main(void) {
	int server_sfd, client_sfd, bytes_recv;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sock_size;
	int yes = 1;
	char tx_buf[128], rx_buf[128];
	int i;
	
	signal(SIGCHLD, handler);

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

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
		perror("setsockopt() error");
		exit(1);
	}
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(10000); //server port number setting
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	memset(&(server_addr.sin_zero), '\0', 8);

	//server ip & port number setting
	if(bind(server_sfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
		perror("bind() error");
		exit(1);
	}

	//client backlog setting
	if(listen(server_sfd, 5) == -1) {
		perror("listen() error");
		exit(1);
	}

	while(1) {
		
		sock_size = sizeof(struct sockaddr_in);

		//wait for client request
		if((client_sfd = accept(server_sfd, (struct sockaddr *)&client_addr, &sock_size)) == -1) {
			perror("accept() error");
			continue;
		}

		printf("server : got connection from %s \n", inet_ntoa(client_addr.sin_addr));

		if(!fork())	{
			close(server_sfd);
			for(i=1; ; i++){
				memset(tx_buf, 0, sizeof(tx_buf));
				memset(rx_buf, 0, sizeof(rx_buf));
				//wait for rx data from client	
				if((bytes_recv = recv(client_sfd, rx_buf, sizeof(rx_buf), 0)) == -1) {
					perror("recv");
					exit(1);
				}
				if(bytes_recv == 0) 
					break;	
				printf("Server Rx(%d) : %s", getpid(), rx_buf);
				sprintf(tx_buf, "Hi_%d, client(from %s)~~\n", i, inet_ntoa(server_addr.sin_addr));
				//send data to client
				if(send(client_sfd, tx_buf, strlen(tx_buf)+1, 0) == -1) 
					perror("send");	
			}
			printf("Server(%d): Client Connection Socket Closed!!\n", getpid());
			//close client socket connection		
			close(client_sfd);
			exit(0);
		}
	}
	return 0;
}

 

02-2.mytcpserver_nonblock.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>   
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>   
#include <sys/wait.h>
#include <pthread.h>

void * server_function (void * args) {
	int bytes_recv;
	int sockfd = *((int*)args);
	char tx_buf[128], rx_buf[128];
	
	for(int i=1; ; i++) {
		memset(tx_buf, 0, sizeof(tx_buf));
		memset(rx_buf, 0, sizeof(rx_buf));
		if((bytes_recv = recv(sockfd, rx_buf, sizeof(rx_buf), 0)) == -1){
			perror("recv");
			exit(1);
		}
		if(bytes_recv == 0) break;	
		printf("Server Rx(%d) : %s", getpid(), rx_buf);
		sprintf(tx_buf, "Hi_%d, client(from %d)~~\n", i, getpid());
		if(send(sockfd, tx_buf, strlen(tx_buf)+1, 0) == -1) perror("send");	
	}
	printf("Server(%d): Client Connection Socket Closed!!\n", getpid());
	close(sockfd);
	return NULL;
}

int main(void){
	int server_sfd, client_sfd;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sock_size;
	int yes = 1;
	int i;
	pthread_t tid;

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

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
		perror("setsockopt() error");
		exit(1);
	}
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(10000); //server port number setting
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	memset(&(server_addr.sin_zero), '\0', 8);

	//server ip & port number setting
	if(bind(server_sfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){
		perror("bind() error");
		exit(1);
	}

	//client backlog setting
	if(listen(server_sfd, 5) == -1){
		perror("listen() error");
		exit(1);
	}

	while(1){
		sock_size = sizeof(struct sockaddr_in);

		//wait for client request
		if((client_sfd = accept(server_sfd, (struct sockaddr *) &client_addr, &sock_size)) == -1){
			perror("accept() error");
			continue;
		}

		printf("server : got connection from %s \n", inet_ntoa(client_addr.sin_addr));
		pthread_create(&tid, NULL, server_function, &client_sfd);
	}
	return 0;
}

 

02-2.mytcpserver_thread.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>   
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>   
#include <sys/wait.h>
#include <pthread.h>

void * server_function (void * args) {
	int bytes_recv;
	int sockfd = *((int*)args);
	char tx_buf[128], rx_buf[128];
	
	for(int i=1; ; i++) {
		memset(tx_buf, 0, sizeof(tx_buf));
		memset(rx_buf, 0, sizeof(rx_buf));
		if((bytes_recv = recv(sockfd, rx_buf, sizeof(rx_buf), 0)) == -1){
			perror("recv");
			exit(1);
		}
		if(bytes_recv == 0) break;	
		printf("Server Rx(%d) : %s", getpid(), rx_buf);
		sprintf(tx_buf, "Hi_%d, client(from %d)~~\n", i, getpid());
		if(send(sockfd, tx_buf, strlen(tx_buf)+1, 0) == -1) perror("send");	
	}
	printf("Server(%d): Client Connection Socket Closed!!\n", getpid());
	close(sockfd);
	return NULL;
}

int main(void){
	int server_sfd, client_sfd;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sock_size;
	int yes = 1;
	int i;
	pthread_t tid;

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

	if(setsockopt(server_sfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
		perror("setsockopt() error");
		exit(1);
	}
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(10000); //server port number setting
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	memset(&(server_addr.sin_zero), '\0', 8);

	//server ip & port number setting
	if(bind(server_sfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){
		perror("bind() error");
		exit(1);
	}

	//client backlog setting
	if(listen(server_sfd, 5) == -1){
		perror("listen() error");
		exit(1);
	}

	while(1){
		sock_size = sizeof(struct sockaddr_in);

		//wait for client request
		if((client_sfd = accept(server_sfd, (struct sockaddr *) &client_addr, &sock_size)) == -1){
			perror("accept() error");
			continue;
		}

		printf("server : got connection from %s \n", inet_ntoa(client_addr.sin_addr));
		pthread_create(&tid, NULL, server_function, &client_sfd);
	}
	return 0;
}

 

 

댓글수0