如何使得服务器面向多个客户端

         一个服务器和一个客户端可以很轻松的去写进行搭建连接的程序 但是客户端不止一个的同时就需要你去想一想

何构思设置了 下面是自己利用进程知识写的两段代码 :

服务器代码段:

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

#define SERV_PORT 9000

#define BUFF_SIZE 1024

void handle_child(int sig)
{
	int status ;
	pid_t pid ;
	while((pid = waitpid(-1,&status,WNOHANG))>0) ;
	printf("a child has dead\n")  ;
}

int server_request(int cfd)
{
	int readSize, writeSize;
	char buff[BUFF_SIZE] = {'\n'};
	int ret = 0;
	int i;
	
	while (readSize = read(cfd, buff, sizeof(buff)))
	{
		if (readSize == -1)
		{
			perror("read");
			return -1;
		}
		
		for (i = 0; i < strlen(buff); i++)
		{
			buff[i] += 'a' - 'A';
		}

		writeSize = write(cfd, buff, strlen(buff));
		if (writeSize == -1)
		{
			perror("write");
			return -1;
		}
		memset(buff, 0, sizeof(buff));
	}
	
}

int main()
{
	int listen_sockfd;
	int ret;
	struct sockaddr_in server_addr;  // 服务器地址结构
	struct sockaddr_in client_addr;  // 客户端的地址
	
	// 创建监听套接字
	listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listen_sockfd == -1)
	{
		perror("create socket error");
		return -1;
	}
	
	// 初始化服务器地址结构
	bzero(&server_addr, sizeof(server_addr));          // 将地址结构变量清零
 	server_addr.sin_family = AF_INET;                  // 选择IPV4地址
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);   // 监听本地任意IP地址
	server_addr.sin_port = htons(SERV_PORT);           // 将本地端口号转化为网络端口号
	
	// 绑定本地地址和端口号
	ret = bind(listen_sockfd, (struct sockaddr *)&server_addr, sizeof (server_addr));
	if (ret == -1)
	{
		perror ("bind error");
		return -1;
	}

	// 监听套接字
	ret = listen(listen_sockfd, 20);
	if (ret == -1)
	{
		perror("listen error");
		return -1;
	}
	signal(SIGCHLD,handle_child) ;
	
	while(1)
	{
		int clientfd;
		socklen_t client_len = sizeof(client_addr);
		printf ("waiting for client to connect.....\n");
		
		clientfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &client_len);
		if (clientfd == -1)
		{
			perror("accept error");
			return -1;
		}
		
		printf ("the client addr is %s\n", inet_ntoa(client_addr.sin_addr));
		
		pid_t ret=fork() ;
		switch(ret)
		{
			case 0 :
			{
				close(listen_sockfd) ;
				// 客户端连接上, 进行通信,通信使用新的套接字
		        server_request(clientfd);
				close(clientfd) ;
				exit(0) ;
			}
			case -1 :
			{
				perror("fork") ;
				return -1 ;
			}
			default :
			{
				close(clientfd) ;
				break ;
			}
		}
		
	}
	
	return 0;
}

客户端代码段:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define SERV_PORT 9000

#define BUFF_SIZE 1024

int ask_server(int sfd)
{
	char buff[BUFF_SIZE] = {0};
	//fgets(buff, sizeof(buff), stdin);
	
	while (1)
	{
		memset(buff, 0, sizeof(buff));
		scanf("%s", buff);
		if (strncmp("end", buff, 3) == 0)
		{
			break;
		}
		
		int writeSize = write(sfd, buff, strlen(buff));
		if (writeSize == -1)
		{
			perror("write");
			return -1;
		}
		
		memset(buff, 0, sizeof(buff));
		int readSize = read(sfd, buff, sizeof(buff));
		if (readSize == -1)
		{
			perror("read");
			return -1;
		}
		
		printf ("read bytes : %d buff: %s\n", readSize, buff);
	}
	
}


int main(int argc, char *argv[])
{
	int server_sockfd;
	int ret;
	struct sockaddr_in client_addr; 
	
	if (argc != 2)
	{
		printf ("Usage:./client IP_ADDRESS\n");
		return -1;
	}
	
	// 创建监听套接字
	server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (server_sockfd == -1)
	{
		perror("create socket error");
		return -1;
	}
	
	// 初始化服务器地址结构
	bzero(&client_addr, sizeof(client_addr));     // 将地址结构变量清零
	client_addr.sin_family = AF_INET;             // 选择IPV4地址
	inet_aton(argv[1], &client_addr.sin_addr);    // 填写服务器地址
	client_addr.sin_port = htons(SERV_PORT);      // 填写服务器端口

	// 连接服务器
	ret = connect(server_sockfd, (struct sockaddr *)&client_addr,  sizeof (client_addr));
	if (ret != 0)
	{
		perror("connect error");
		return -1;
	} 
	
	ask_server(server_sockfd);
	close(server_sockfd);

	return 0;
}
其实还有其他一些方法 比如线程之类的 因而我们要不断积累 提高自己的水平 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值