Chinaunix首页 | 论坛 | 博客
  • 博客访问: 866230
  • 博文数量: 156
  • 博客积分: 6553
  • 博客等级: 准将
  • 技术积分: 3965
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-22 18:36
文章存档

2012年(3)

2011年(43)

2010年(110)

分类: LINUX

2010-10-04 00:07:35

需要实现功能如下:
1.服务器端功能如下:
广播通知客服端登录/退出
接受客服端发来的消息,广播给所有用户
广播系统消息
2.客服端功能如下:
接收服务器发来的消息并显示
发送消息给服务器端
 
实现代码如下:
1.服务器端代码:
 

#include
#include
#include
#include
#include
#include
#include
#define R 1
#define U 2
#define B 3
#define N 64
typedef struct
{
 int type;
 char name[16];
 char text[N];
} MESG;
typedef struct sockaddr SA;
typedef struct _node_
{
 struct sockaddr_in cliaddr;
 struct _node_ *next;
} linknode, *linklist;
linklist CreateEmptyLinklist()
{
 linklist h;
 h = (linklist)malloc(sizeof(linknode));
 h->next = NULL;
 return h;
}
void AddUser(int sockfd, linklist h, struct sockaddr_in peeraddr, MESG buf)
{
 linklist p;
 printf("AddUser()\n");
 p = (linklist)malloc(sizeof(linknode));
 p->cliaddr = peeraddr;
 p->next = h->next;
 h->next = p;
 p = p->next;
 sprintf(buf.text, "%s is online\n", buf.name);
 strcpy(buf.name, "system");
 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));
 return;
}
void DelUser(int sockfd, linklist h, struct sockaddr_in peeraddr, MESG buf)
{
 linklist p = h->next;
 printf("DelUser()\n");
 sprintf(buf.text, "%s is offline\n", buf.name);
 strcpy(buf.name, "system");
 while (p != NULL)
 {
  if ((p->cliaddr.sin_addr.s_addr == peeraddr.sin_addr.s_addr) &&
   (p->cliaddr.sin_port == peeraddr.sin_port))
  {
   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));
 return;
}
void Broadcast(int sockfd, linklist h, MESG buf)
{
 h = h->next;
 while (h != NULL)
 {
  sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&h->cliaddr, sizeof(h->cliaddr));
  h = h->next;
 }
 return;
}
int main(int argc, char *argv[])
{
 int sockfd;
 MESG buf;
 struct sockaddr_in myaddr, peeraddr;
 socklen_t peerlen;
 linklist h;
 if (argc < 3)
 {
  printf("Usage : %s \n", argv[0]);
  exit(-1);
 }
 if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
 {
  perror("fail to socket");
  exit(-1);
 }
 bzero(&myaddr, sizeof(myaddr));
 myaddr.sin_family = PF_INET;
 myaddr.sin_port = htons(atoi(argv[2]));
 myaddr.sin_addr.s_addr = inet_addr(argv[1]);
 if (bind(sockfd, (SA *)&myaddr, sizeof(myaddr)) < 0)
 {
  perror("fail to bind");
  exit(-1);
 }
 h = CreateEmptyLinklist();
 while ( 1 )
 {
  peerlen = sizeof(peeraddr);
  recvfrom(sockfd, &buf, sizeof(buf), 0, (SA *)&peeraddr, &peerlen);
  switch ( buf.type )
  {
  case R:
   AddUser(sockfd, h, peeraddr, buf);
   break;
  case U:
   DelUser(sockfd, h, peeraddr, buf);
   break;
  case B:
   Broadcast(sockfd, h, buf);
   break;
  }
 }
 return 0;
}
2.客服端代码如下:

#include
#include
#include
#include
#include
#include
#include
#include
#define R 1
#define U 2
#define B 3
#define N 64
typedef struct
{
 int type;
 char name[16];
 char text[N];
} MESG;
typedef struct sockaddr SA;
/*
typedef struct _node_
{
 struct sockaddr_in cliaddr;
 struct _node_ *next;
} linknode, *linklist;
*/
int main(int argc, char *argv[])
{
 int sockfd;
 MESG buf;
 struct sockaddr_in servaddr;
 if (argc < 3)
 {
  printf("Usage : %s \n", argv[0]);
  exit(-1);
 }
 printf("please input your login name : ");
 fgets(buf.name, 16, stdin);
 buf.name[strlen(buf.name)-1] = '\0';
 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 ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
 {
  perror("fail to socket");
  exit(-1);
 }
 // XXX: register
 buf.type = R;
 sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr, sizeof(servaddr));
 pid_t pid;
 if ((pid = fork()) == 0)  // child process
 {
  while ( 1 )
  {
   recvfrom(sockfd, &buf, sizeof(buf), 0, NULL, NULL);
   printf("[%s] %s", buf.name, buf.text);
  }
 }
 else   // parent process
 {
  buf.type = B;
  while ( 1 )
  {
   printf(" ");
   fgets(buf.text, N, stdin);
   if (strncmp(buf.text, "quit", 4) == 0)
   {
    buf.type = U;
    sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr,sizeof(servaddr));
    usleep(100000);
    kill(pid, SIGKILL);
    exit(0);
   }
   sendto(sockfd, &buf, sizeof(buf), 0, (SA *)&servaddr,sizeof(servaddr));
  }
 } 
 return 0;
}
阅读(3206) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~