📄 zzj_srv.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 + -