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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值