1. 程式人生 > >Linux C: 基於C/S的多執行緒網路程式設計 2 (多客戶端)

Linux C: 基於C/S的多執行緒網路程式設計 2 (多客戶端)

客戶端:

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

char name[64];

int tcp_connect(const char* ip, int port)  //用於客戶端的連線
{
	int sfd = socket(AF_INET, SOCK_STREAM, 0); //向系統申請註冊新的socket
	if(sfd == -1)
	{
		perror("Socket error");
		exit(-1);
	}
	struct sockaddr_in serveraddr;
	memset(&serveraddr, 0, sizeof(struct sockaddr) );
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(port);
	serveraddr.sin_addr.s_addr = inet_addr(ip);
	//將sfd連線到制定的伺服器serveraddr
	if( connect(sfd,(struct sockaddr*) &serveraddr,sizeof(struct sockaddr) ) == -1 )
	{
		perror("Connect error");
		close(sfd); 
		exit(-1); 
	}
	return sfd;
}


void signalhandler(void)
{
	sigset_t sigSet;
	sigemptyset(&sigSet);
	sigaddset(&sigSet,SIGINT);
	sigaddset(&sigSet,SIGQUIT);
	sigprocmask(SIG_BLOCK,&sigSet,NULL); 	
}

void* pthread_send(void *arg)
{
	int *temp;
	temp = (int *)arg; 
	char buf[128];
	while(1)
	{
		memset(buf,0,sizeof(buf));
		fgets(buf, sizeof(buf), stdin);
		strcpy(buf, strcat(name, buf));
		send(*temp, buf, 512, 0); //向sfd服務端傳送資料
	} 
}


void* pthread_recv(void *arg)
{
	int *temp;
	temp = (int *)arg;
	char buf[128] = {0};
	while(1)
	{
		memset(buf,0,sizeof(buf));
		recv(*temp, buf, sizeof(buf), 0); //接收sfd服務端的資料
		puts(buf);
	}
}

int main(int argc,char **argv)
{
	printf( "Please enter your name: " );
	fgets(name, sizeof(name), stdin);

    int ret_send;
    int ret_recv;
 
	pthread_t id1;
    pthread_t id2;
					
	if(argc < 3)
	{
		printf("usage:./client ip port\n");
		exit(-1);
	}
	int sfd = tcp_connect(argv[1],atoi(argv[2]));
	
	int *b = &sfd;
    ret_send = pthread_create(&id1, NULL, (void*)pthread_send, (void*)b);
	ret_recv = pthread_create(&id2, NULL, (void*)pthread_recv, (void*)b);

	pthread_join(id1, NULL);
    pthread_join(id2, NULL);

	close(sfd);
	return 0;
}


伺服器端:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<signal.h>
#include<pthread.h>

int tcp_init(const char * ip, int port)
{
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if( sfd == -1)
	{
		perror("Socket error");
		exit(-1);
	}
	struct sockaddr_in serveraddr;
	memset( &serveraddr, 0, sizeof( struct sockaddr));
	serveraddr.sin_port = htons(port);
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = inet_addr(ip);
	if (bind(sfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr) ) == -1)
	{
		perror("Bind error" );
		close(sfd);
		exit(-1);
	}
	if(listen(sfd, 10) == -1)
	{
		perror("Listen error" );
		close(sfd);
		exit(-1);
	}
	return sfd;
} 

int tcp_accept(int sfd)
{
	struct sockaddr_in clientaddr;
	memset(&clientaddr, 0, sizeof(struct sockaddr));
	int addrlen = sizeof(struct sockaddr);
	int new_fd = accept(sfd, (struct sockaddr*)&clientaddr, &addrlen);
	if(new_fd == -1)
	{
		perror("accept error");
		close(sfd);
		exit(-1);
	}
	printf("%s %d success connect...\n", inet_ntoa(clientaddr.sin_addr), 
					ntohs(clientaddr.sin_port));
	return new_fd;
} 

void signalhandler(void)
{
	sigset_t sigSet;
	sigemptyset(&sigSet);
	sigaddset(&sigSet, SIGINT);
	sigaddset(&sigSet, SIGQUIT);
	sigprocmask(SIG_BLOCK, &sigSet, NULL);
}

char buf[128];

typedef struct
{
	int sfd;
	int client_1;
	int client_2;
}tcp_info;

void* pthread_listen_client_1(void* arg)
{
	tcp_info *temp;
	temp = (tcp_info *)arg;
	while(1)
	{
		char buf[128] = {0};
		if(recv(temp->client_2, buf, sizeof(buf), 0) == -1)
		{
			printf("Recv from client_2  error");
			exit(-1);
		}
	
		if(send(temp->client_1, buf, sizeof(buf), 0) == -1)
		{
			printf("Send to client_1 error");
			exit(-1);
		}
	}
}

void* pthread_listen_client_2(void* arg)
{
	tcp_info *temp;
	temp = (tcp_info *)arg;
	while(1)
	{
		char buf[128] = {0};
		if(recv(temp->client_1, buf, sizeof(buf), 0) == -1)
		{
			printf("Recv from client_1 error");
			exit(-1);
		}

		if(send(temp->client_2, buf, sizeof(buf), 0) == -1)
		{
			printf("Send to client_2 error");
			exit(-1);
		}
	}
}


int main (int argc, char **argv)
{
	int client_1;
	int client_2;
	
	pthread_t client1_listen;
	pthread_t client2_listen;

	if(argc < 3)
	{
		printf( "Usage:./server server_ip server_port\n" );
		exit(-1);
	}
	signalhandler();
	int sfd = tcp_init(argv[1], atoi(argv[2]));

	client_1 = tcp_accept(sfd);
	printf("Waiting for another client......\n");
	client_2 = tcp_accept(sfd);
	printf("Connected successufly!\n");
	
	tcp_info *info;
	info = (tcp_info*)malloc(sizeof(tcp_info));
	info->sfd = sfd;
	info->client_1 = client_1;
	info->client_2 = client_2;

	pthread_create(&client1_listen, NULL, pthread_listen_client_1, (void *)info );
	pthread_create(&client2_listen, NULL, pthread_listen_client_2, (void *)info );
	
	pthread_join(client1_listen, NULL);
	pthread_join(client2_listen, NULL);
	
	return 0;
}