|
/*********************************客户端***************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef struct sockaddr SA;
#define N 64
#define R 1
#define U 2
#define B 3
#define E 4
typedef struct
{ int type; char name[16]; char text[N];
} MSG;
int main(int argc, char *argv[])
{ int sockfd; MSG buf; pid_t pid; struct sockaddr_in servaddr;
if (argc < 3) { printf("Usage : %s <ip> <port>\n", argv[0]); return -1; }
printf("pleast input your name : "); fgets(buf.name, 16, stdin); buf.name[strlen(buf.name)-1] = '\0';
// XXX int socket(int domain, int type, int protocol); if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { perror("fail to socket"); exit(-1); }
bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = PF_INET; servaddr.sin_port = htons(atoi(argv[2])); servaddr.sin_addr.s_addr = inet_addr(argv[1]);
buf.type = R; sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr));
if ((pid = fork()) < 0) { perror("fail to fork"); exit(-1); } else if (pid == 0) // receive message { while ( 1 ) { recvfrom(sockfd, &buf, sizeof(buf), 0, NULL, NULL); if (buf.type == E) break; printf("\n *** [%s] %s", buf.name, buf.text); } printf("server is down, exit...\n"); kill(getppid(), SIGUSR1); exit(0); } else // send message { usleep(100000); buf.type = B; while ( 1 ) { printf("%s > ", buf.name); fgets(buf.text, N, stdin); if (strcmp(buf.text, "quit\n") == 0) break; sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr)); usleep(100000); } buf.type = U; sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr)); usleep(100000); kill(pid, SIGUSR1); exit(0); }
return 0;
}
/********************************服务器**************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef struct sockaddr SA;
#define N 64
#define R 1
#define U 2
#define B 3
#define E 4
typedef struct
{ int type; char name[16]; char text[N];
} MSG;
typedef struct _node_
{ struct sockaddr_in cliaddr; struct _node_ *next;
} linknode, *linklist;
void AddUser(int sockfd, MSG buf, struct sockaddr_in peeraddr, linklist h)
{ linklist p;
p = (linklist)malloc(sizeof(linknode)); p->next = h->next; h->next = p; p->cliaddr = peeraddr;
sprintf(buf.text, "%s is online\n", buf.name); strcpy(buf.name, "system"); p = p->next; while (p != NULL) { sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&p->cliaddr, sizeof(peeraddr)); p = p->next; } strcpy(buf.text, "welcome to farsight chat room\n"); sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&peeraddr, sizeof(peeraddr));
}
void DelUser(int sockfd, MSG buf, struct sockaddr_in peeraddr, linklist h)
{ linklist p = h->next;
sprintf(buf.text, "%s is offline\n", buf.name); strcpy(buf.name, "system"); while (p != NULL) { if (memcmp(&p->cliaddr, &peeraddr, sizeof(peeraddr)) == 0) { h->next = p->next; free(p); } else { sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&p->cliaddr, sizeof(peeraddr)); h = h->next; } p = h->next; } strcpy(buf.text, "see you next time\n"); sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&peeraddr, sizeof(peeraddr));
}
void Broadcast(int sockfd, MSG buf, linklist h)
{ h = h->next;
while (h != NULL) { sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&h->cliaddr, sizeof(h->cliaddr)); h = h->next; }
}
int main(int argc, char *argv[])
{ int sockfd; MSG buf; pid_t pid; struct sockaddr_in servaddr, peeraddr; socklen_t peerlen = sizeof(peeraddr);
if (argc < 3) { printf("Usage : %s <ip> <port>\n", argv[0]); return -1; }
// XXX int socket(int domain, int type, int protocol); if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { perror("fail to socket"); exit(-1); }
bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = PF_INET; servaddr.sin_port = htons(atoi(argv[2])); servaddr.sin_addr.s_addr = inet_addr(argv[1]);
if (bind(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0) { perror("fail to bind"); exit(-1); }
if ((pid = fork()) < 0) { perror("fail to fork"); exit(-1); } else if (pid == 0) // receive message { linklist h; h = (linklist)malloc(sizeof(linknode)); h->next = NULL;
while ( 1 ) { recvfrom(sockfd, &buf, sizeof(buf), 0, (SA *)&peeraddr, &peerlen); switch ( buf.type ) { case R : AddUser(sockfd, buf, peeraddr, h); break; case U : DelUser(sockfd, buf, peeraddr, h); break; case B : case E : Broadcast(sockfd, buf, h); break; } if (buf.type == E) exit(0); } } else // send message { buf.type = B; strcpy(buf.name, "system"); while ( 1 ) { printf("server > "); fgets(buf.text, N, stdin); if (strcmp(buf.text, "quit\n") == 0) break; sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr)); usleep(100000); } buf.type = E; sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr)); usleep(100000); exit(0); }
return 0;
}
|