⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zzj_srv.c

📁 linux环境下多人聊天程序。包括服务器端和客户端程序
💻 C
字号:
/*inet.h*/  
#ifndef   __INET_H__  
#define __INET_H__  
#include <stdio.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <netdb.h>
#include <arpa/inet.h>  
#include <fcntl.h>  
#include <sys/time.h>  
#include <unistd.h>  
#include <sys/time.h>  
 
#define MAX_CLIENT 10  
#define READ 0  
#define WRITE 1  
#define MAX_LINE 1000  
#define MAX_NAME 100  
#define SETNAME "/name"  
#define __SELECT__  
 
#endif  
 
/*server.c*/  
#include   <signal.h>  
#include   <sys/wait.h>  
  
int init_ser(const char *host, const char *port, socklen_t *addrlenp);    
int max(int a, int b)  
{  
	int themax;  
  
        if(a > b)   
		themax = a;  
        else   
		themax = b;  
        return themax;  
}  
  
void set_name(char *line, char *name)    
{  
        strcpy(name, &line[1]);  
        sprintf(line, "%s join the room\n", name);  
}  
  
void add_name(char *line, char *name)  
{  
        char theline[MAX_LINE];  
  
        strcpy(theline, name);  
        strcat(theline, ":");  
        strcat(theline, line);  
        strcpy(line, theline);  
}  
  
int user_free(int user_link[MAX_CLIENT])  
{  
	int i = 0;  
 
	while((user_link[i] != 0)&&(i < MAX_CLIENT))   
		i++;  
	if(i == MAX_CLIENT)   
		return -1;  
	return i;  
}  
  
void add_sockset(fd_set *sockset, int sockfd, int *user_link, int *userfd)  
{  
        int i;  
 
        FD_ZERO(sockset);  
        FD_SET(sockfd, sockset);  
        for(i = 0; i < MAX_CLIENT; i++)   
	{  
                if(user_link[i] == 1)   
		{  
                        FD_SET(userfd[i], sockset);  
                }  
        }  
} 
char *ipv6addr (struct sockaddr_in6 *sa) 
{
	static char string[40];
	unsigned char *p, *q = string;
	int i = 1;
	for (p = sa->sin6_addr. in6_u. u6_addr8; i<=8; i++) {
		sprintf (q, "%02x", *p++); q+=2;
		sprintf (q, "%02x", *p++); q+=2;
		sprintf (q++, ":");
	}
	return string;
}
  
int main(int argc, char **argv)  
{  
	int sockfd, new_sockfd;  
	int user_link[MAX_CLIENT];
	int userfd[MAX_CLIENT];  
	char username[MAX_CLIENT][MAX_NAME];  
	int userCount;  
	char line[MAX_LINE];  
	struct sockaddr_in6 cli_addr;  
	socklen_t cli_len;
        FILE *file;  
        int port;  
        int length, i, j;  
        fd_set sockset;  
        int maxfd = 0;  
 
        sockfd = init_ser(argv[1], argv[2], &cli_len);  
 
	listen(sockfd, MAX_CLIENT);  

	for(i = 0; i < MAX_CLIENT; i++)   
	{  
		user_link[i] = 0;  
                username[i][0] = '\0';  
        }  

	userCount = 0;  
        FD_ZERO(&sockset);  
        FD_SET(sockfd, &sockset);  
        maxfd = max(maxfd, sockfd+1);  
 
	while(1)   
	{  
                select(maxfd, &sockset, NULL, NULL, NULL);  
		if(FD_ISSET(sockfd, &sockset) && (userCount = user_free(user_link)) >= 0)   		  {    
			new_sockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);  
			printf("connection from %39s\n", ipv6addr(&cli_addr));
			if(new_sockfd < 0)   
			{  
				user_link[userCount] = 0;  
                                printf("acc error\n");  
				exit(1);
			}   
			else   
			{  
				user_link[userCount] = 1;  
                                userfd[userCount] = new_sockfd;  
                                FD_SET(new_sockfd, &sockset);  
                                maxfd = max(maxfd, new_sockfd+1);  
                        }  
                }   //   if   userCount   >=   0  
                for(i = 0; i < MAX_CLIENT; i++)   
		{  
                        if((user_link[i] == 1) && (FD_ISSET( userfd[i], &sockset)))   
			{  
                                length = read( userfd[i], line, MAX_LINE);  
                                if(length == 0)   {   //   socket   is   closed.  
                                        user_link[i] = 0;  
                                        username[i][0] ='\0';  
                                        FD_CLR(userfd[i], &sockset);  
                                }   
				else   
					if(length > 0)
					{  
                                        	line[length] = '\0';  
                                        	if   ((line[0] == '/') && (username[i][0] == '\0'))   
						{  
                                                	set_name(line, username[i]);  
							printf("A new name %s\n", line);
                                        	}   
						else   
						{  
                                        	        add_name(line, username[i]);  
                                        	}  
                                        	for(j = 0; j < MAX_CLIENT; j++)   
						{  
                                                	if((j != i) && (user_link[j] == 1))   
							{  
                                                        	write(userfd[j], line, strlen(line));  
                                                	}  
                                        	}  
                                	}   //   length   >0  
                        }   //   user_link[i]   ==   1  
                }   //   for                                  
                add_sockset(&sockset, sockfd, user_link, userfd);  
	}   //while  
        return 0;  
}  
 
int init_ser(const char *host, const char *port, socklen_t *addrlenp)  
//If success, return sockfd, else return 0  
{   
	int listenfd, n;
	const int on = 1;
	struct addrinfo hints, *res;
	bzero (&hints, sizeof (struct addrinfo));
	hints.ai_flags = AI_PASSIVE;
	hints.ai_family = AF_INET6;
	hints.ai_socktype = SOCK_STREAM;
	n = getaddrinfo(host, port, &hints, &res); //return 0 on success
	if(n != 0) 
	{
		perror ("error: getaddrinfo in init_ser") ;
		exit (1);
	}
	listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if (listenfd < 0) 
	{
		perror ("error: socket in init_ser") ;
		exit (1);
	}
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if(bind(listenfd, res->ai_addr, res->ai_addrlen) != 0) 
	{
		perror ("error: bind in init_ser");
		exit (1);
	}
	
	*addrlenp = res->ai_addrlen; //size of protocol address return (listenfd);
	return listenfd;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -