Linux c语言 聊天室

来源:互联网 发布:deepin linux硬盘安装 编辑:程序博客网 时间:2024/06/01 07:47

/*hanfng:

./serverroom 192.168.1.005 10000 


*/

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>

#define N 1024
#define L 1
#define B 2
#define Q 3


//消息类型
 typedef  struct   //名字结构体
 {
  char type;  //序号 名字;
  char name[N];
  char text[N];
 }MSG;

 
//节点类型
 typedef struct node    //链表成员———结构体
 {
  struct sockaddr_in clientaddr;
  struct node *next;
 }listnode,*linklist;

 linklist linklist_create()   //创建链表 ——函数
 {
  linklist H;
  H = (listnode*)malloc(sizeof(listnode));
  H -> next = NULL;
  return H;
 }

//------------------------
  void process_login(int sockfd,linklist H,struct sockaddr_in clientaddr,MSG msg);//登录

  void process_chat(int sockfd,linklist H ,struct sockaddr_in clientaddr,MSG msg);//消息

  void process_quit(int sockfd,linklist H,struct sockaddr_in clientaddr,MSG msg);//下线

//--------------------------
int main(int argc, const char *argv[])
{
 linklist *H = NULL;
 int sockfd;
 int connfd;
 char buf[N] = {};
 MSG msg;
 if(argc < 3)    //终端传参
 {
  fprintf(stderr,"Usage  : %s ip port \n",argv[0]);
  return -1;
 }

 if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0)  //创建套接字
 {
  perror("fail to socket\n");
  return -1;
 }
 struct sockaddr_in serveraddr;
 struct sockaddr_in clientaddr;
 serveraddr.sin_family = AF_INET;    //填充
 serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
 serveraddr.sin_port = htons(atoi(argv[2]));
 if(bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0)  //绑定套接字
 {
  perror("fail to bind\n");
  return -1;
 }

 socklen_t addrlen  = sizeof(struct sockaddr);  //缓冲区地址长度

  //H =linklist_create();   //调用创建 链表函数

 pid_t pid;     //创建进程
 pid = fork();
 if(pid < 0)
 {
  perror("fail to pid\n");
  return -1;
 }

 if(pid == 0)     //childer
 { 
 // memset(&msg,0,sizeof(msg));
  strcpy(msg.name,"server");
  msg.type = B;
  while(1)
  {
   fgets(buf,N,stdin);
   buf[strlen(buf) -1] = '\0';
   sprintf(msg.text,"%s 说 %s",msg.name,buf);
   sendto(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&serveraddr,sizeof(serveraddr));

  }
 
 
 }
 else   //father
 { 
  linklist H = linklist_create() ;  //创建链表 ——函数
  H = linklist_create();//chuangjian xin lainbiap
  while(1)
  {
   recvfrom(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&clientaddr,&addrlen);
   printf("+++++++++++++++++++++++++++++++++++++++++++++++++\n");
   printf("发言者ID 端口 : %s -- %d  -- %s  \n ",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port),buf);

   switch(msg.type)
   {
    case'L':
     process_login(sockfd,H,clientaddr,msg);
     break;
    case'B':
     process_chat(sockfd,H,clientaddr,msg);
     break;
    case'Q':
     process_quit(sockfd,H,clientaddr,msg);

   }
  }
 }

 return 0;
}
  void process_login(int sockfd,linklist H,struct sockaddr_in clientaddr,MSG msg)
  {
   linklist p = H -> next;
   
   
   sprintf(msg.text,"%s login",msg.name);//拼接字符串
   printf("  %s\n",msg.text);
   while(p)
    
   {
    sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&p->clientaddr,sizeof(clientaddr));

    p = p -> next;
   }
   linklist temp ;
   temp = (linklist)malloc(sizeof(listnode));
   temp -> clientaddr  = clientaddr;
   temp -> next = H -> next;
   H -> next = temp;
  
  }

  void process_chat(int sockfd,linklist H ,struct sockaddr_in clientaddr,MSG msg)
  {
   linklist p = H -> next;
   char s[N] = {};
   sprintf(s,"%s 说: [%s]  <0.0>   ",msg.name,msg.text);
   strcpy(msg.text,s);
   printf("%s\n",s);
   while(p)
   {
    if(memcmp(&clientaddr,&p-> clientaddr,sizeof(clientaddr)) != 0)
    {
     sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->clientaddr,sizeof(struct sockaddr));

    }
    p = p -> next;
   }
  }
 
  void process_quit(int sockfd,linklist H,struct sockaddr_in clientaddr,MSG msg)
  {
   linklist p =  H;
   linklist q;
   sprintf(msg.text,"%s下线了!!",msg.name);
   while(p -> next != NULL)
   {
    if(memcmp(&clientaddr,&p-> next -> clientaddr,sizeof(clientaddr)) == 0)
    {
     q = p -> next;
     p -> next = q -> next;
     free(q);
     q = NULL;
    }
    else
    {
     sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&p -> next -> clientaddr,sizeof(p-> next -> clientaddr));
     p = p -> next;
    }
   }
  }
 
 
 

 

 

 

 

 

/*hanfng:

./fclientroom 192.168.1.005 10000 


*/

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<signal.h>
#define L 1
#define B 2
#define Q 3
#define N 1024
 typedef  struct msg
 {
  char type;
  char name[N];
  char text[N];
 }MSG;


int main(int argc, const char *argv[])
{
 int sockfd;
 int connfd;
 char buf[N] = {};
 struct sockaddr_in serveraddr;
 MSG msg;
 if(argc < 3)
 {
  fprintf(stderr,"Usage  : %s ip port \n",argv[0]);
  return -1;
 }

 if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
 {
  perror("fail to socket\n");
  return -1;
 }
 serveraddr.sin_family = AF_INET;
 serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
 serveraddr.sin_port = htons(atoi(argv[2]));
 
 socklen_t addrlen = sizeof(struct sockaddr);

 printf("Input name : ");
 fgets(msg.name,N,stdin);
 msg.name[strlen(msg.name) -1] = '\0';
 msg.type = 'L';
 sendto (sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&serveraddr,addrlen);
 pid_t pid;
 pid = fork();
 if(pid < 0)
 {
  perror("fail to open \n");
  return -1;
 }
 if(pid == 0)    //子进程 send
 {
  while(1)
  {
   fgets(msg.text,N,stdin);
   msg.text[strlen(msg.text) - 1] = '\0';
   //strcpy(msg.text);
   
   if(strncmp(msg.text,"quit",4) == 0)
   {
    msg.type = 'Q';
    sendto(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&serveraddr,addrlen);

    close(sockfd);

    kill(getppid(),SIGKILL); //杀死父 进程
    exit(0);
   }
   else
   {
    msg.type = 'B';
    sendto(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&serveraddr,addrlen);
   }
  }
 
 }
 else      //父进程 recvfrom;
 {
  while(1)
  {
   recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&serveraddr,&addrlen);
   printf("@所有成员:  %s \n",msg.text);
  }
 }
 close(sockfd);
 return 0;
}

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 


 

1 0
原创粉丝点击