/*************************************************************************
> File Name: server.c
> Author: qinf
> Mail:
> Created Time: Thu 03 Apr 2014 09:39:57 AM CST
************************************************************************/
#include "mul_chat.h"
struct linknode {
struct sockaddr_in addr;
struct linknode *next;
};
typedef struct linknode *linklist;
linklist create_linklist();
void insert_linknode(linklist L, struct sockaddr_in client_addr);
void delete_linknode(linklist L, struct sockaddr_in client_addr);
int linklist_len(linklist L);
int main(int argc, char *argv[])
{
int server_fd, serveraddr_len, client_len;
struct sockaddr_in server_addr, client_addr;
int pid, iret, result;
fd_set inputs, testfds;
struct timeval timeout;
char buf[512];
linklist L;
L = create_linklist();
//1.socket
iret = server_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (iret == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
printf("==================\n");
serveraddr_len = sizeof(server_addr);
//2.bind
bind(server_fd, (struct sockaddr*)&server_addr, serveraddr_len);
//3.recvfrom
FD_ZERO(&inputs);
FD_SET(server_fd, &inputs);
while (1) {
testfds = inputs;
result = select(1024, &testfds, NULL, NULL, NULL);
if (result == -1) {
perror("select");
exit(EXIT_FAILURE);
}
if (FD_ISSET(server_fd, &testfds)) {
memset(buf, '\0', 512);
int iret = recvfrom(server_fd, buf, 512, 0, (struct sockaddr*)&client_addr, &client_len);
printf("iret: %d\n", iret);
if (strncmp(buf, "on", 2) == 0) {
//上线,将client的地址结构添加到链表中
insert_linknode(L, client_addr);
printf("--------linklist len = %d\n", linklist_len(L));
} else if (iret == 0) {
//退出,将client从链表中删除
delete_linknode(L, client_addr);
} else {
//向所有client发送
linklist l = L->next;
while(l != NULL) {
//4.sendto
char test_buf[512];
memset(test_buf, 0, 512);
sprintf(test_buf, "from %s: %s", inet_ntoa(l->addr.sin_addr), buf);
sendto(server_fd, test_buf, strlen(test_buf), 0, (struct sockaddr*)&l->addr, sizeof(struct sockaddr));
l = l->next;
}
}
}
if (L == NULL)
break;
}
//5.close
close(server_fd);
}
linklist create_linklist() {
linklist L = (linklist)malloc(sizeof(struct linknode));
// memset(L, 0, sizeof(struct linknode));
L->next = NULL;
return L;
}
void insert_linknode(linklist L,struct sockaddr_in client_addr) {
linklist l = L;
linklist node = (linklist)malloc(sizeof(struct linknode));
node->addr.sin_family = client_addr.sin_family;
node->addr.sin_addr = client_addr.sin_addr;
node->addr.sin_port = client_addr.sin_port;
node->next = l->next;
l->next = node;
}
void delete_linknode(linklist L, struct sockaddr_in client_addr) {
linklist l = L, p;
while (l->next != NULL) {
p = l->next;
if (p->addr.sin_addr.s_addr == client_addr.sin_addr.s_addr) {
l->next = p->next;
free(p);
break;
}
l = l->next;
}
}
int linklist_len(linklist L)
{
linklist l = L->next;
int len = 0;
while (l != NULL) {
++len;
l = l->next;
}
return len;
}
/*************************************************************************
> File Name: client1.c
> Author: qinf
> Mail:
> Created Time: Thu 03 Apr 2014 09:39:48 AM CST
************************************************************************/
#include "mul_chat.h"
int main(int argc, char *argv[])
{
int client_fd, pid, iret;
struct sockaddr_in client_addr, server_addr;
fd_set fd_rd, fd_rd_back;
char stdin_buf[512], socket_buf[512];
//socket
client_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == client_fd) {
perror("socket");
exit(EXIT_FAILURE);
}
FD_ZERO(&fd_rd);
FD_SET(0, &fd_rd);
FD_SET(client_fd, &fd_rd);
//server_addr
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
int len = sizeof(server_addr);
//上线
int ii = sendto(client_fd, "on", 2, 0, (struct sockaddr *)&server_addr, len);
//printf("sendto:ii %d\n", ii);
while (1) {
fd_rd_back = fd_rd;//这个必须放在循环里面,每次初始化
select(1024, &fd_rd_back, NULL, NULL, NULL);
if (FD_ISSET(0, &fd_rd_back)) {
memset(stdin_buf, 0, 512);
iret = read(0, stdin_buf, 512);
if (iret == 0) {
sendto(client_fd, "bye", 3, 0, (struct sockaddr *)&server_addr, len);
break;
}
stdin_buf[iret] = '\0';
ii = sendto(client_fd, stdin_buf, strlen(stdin_buf), 0, (struct sockaddr *)&server_addr, len);
//printf("sendto: ii %d\n", ii);
}
if (FD_ISSET(client_fd, &fd_rd_back)) {
memset(socket_buf, 0, 512);
iret = recvfrom(client_fd, socket_buf, 512, 0, NULL, NULL);
socket_buf[iret] = '\0';
write(1, socket_buf, strlen(socket_buf));
}
}
close(client_fd);
}