day6

day6_第1张图片

服务器

  1 #include
  2 struct Msg
  3 {
  4     char type;
  5     char name[20];
  6     char text[100];
  7 };
  8 typedef struct Node
  9 {
 10     struct sockaddr_in addr;
 11     struct Node *next;
 12 }*Linklist;
 13 Linklist create_node()
 14 {
 15     Linklist p=(Linklist)malloc(sizeof(struct Node));
 16     if(NULL==p)
 17     {
 18         return NULL;
 19     }
 20     p->next=NULL;
 21     return p;
 22 }
 23 Linklist insert_rear(Linklist head,struct sockaddr_in addr)
 24 {
 25     Linklist s=create_node();
 26     if(NULL==s)
 27     {
 28         return head;
 29     }                                                                                                                                                                                                                                                                                                                                                 
 30     s->addr =addr;
 31     if(NULL==head)
 32     {
 33         head==s;
 34     }
 35     else
 36     {
 37         Linklist p=head;
 38         while(p->next!=NULL)
 39         {
 40             p=p->next;
 41         }
 42         p->next=s;
 43     }
 44     return head;
 45 }
 46 int main(int argc, const char *argv[])
 47 {
 48     if(argc!=3)
 49     {
 50         printf("请输入ip地址和端口号\n");
 51         return -1;
 52     }
 53 
 54     //创建套接字
 55     int sfd = socket(AF_INET, SOCK_DGRAM, 0);
 56     //SOCK_DGRAM:表示使用UDP报式套接字通信
 57     if(sfd == -1)
 58     {
 59         perror("socket error");
 60         return -1;
 61     }
 62     printf("sfd = %d\n", sfd);
 63     //绑定
 64     //填充地址信息结构体
 65     struct sockaddr_in sin;
 66     sin.sin_family = AF_INET;
 67     sin.sin_port = htons(argv[2]);       //端口号
 68     sin.sin_addr.s_addr = inet_addr(argv[1]);  //ip地址
 69     //绑定工作
 70     if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
 71     {
 72         perror("bind error");
 73         return -1;
 74     }
 75     //定义变量存放客户端地址信息结构体
 76     struct sockaddr_in cin;
 77     socklen_t socklen = sizeof(cin);
 78     Linklist head=create_node();
 79     head->addr=cin;
 80     struct Msg msg;
 81     pid_t pid=fork();
 82     //发送服务器消息
 83     if(pid>0)
 84     {
 85         while(1)
 86         {
 87             recvfrom(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
 88             if(msg.type=='L')
 89             {
 90                 printf("%s [%s:%d]登录成功\n",msg.name,inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
 91             }
 92             if(msg.type=='C')
 93             {
 94                 printf("%s [%s:%d]chat成功\n",msg.name,inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
 95             }
 96             if(msg.type=='Q')
 97             {
 98                 printf("%s [%s:%d]退出成功\n",msg.name,inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
 99             }
100         }
101     }
102     else if(pid==0)
103     {
104         while(1)
105         {
106             recvfrom(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&cin,sizeof(cin));
107             if(msg.type=='L')
108             {
109                 char buf[128]="";
110                 sprintf(buf,"-----%s登录成功-----\n",msg.name);
111                 insert_rear(head,cin);
112                 Linklist p=head;
113                 while(p->next!=NULL)
114                 {
115                     sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,socklen);
116                     p=p->next;
117                 }
118             }
119             if(msg.type=='C')
120             {
121                 char sbuf[128]="";
122                 sprintf(sbuf,"[%s]:%s\n",msg.name,msg.text);
123                 Linklist s=head;
124                 while(s->next!=NULL)
125                 {
126                     sendto(sfd,sbuf,sizeof(sbuf),0,(struct sockaddr*)&cin,socklen);
127                     s=s->next;
128                 }
129             }
130             if(msg.type=='Q')
131             {
132                 char qbuf[128]="";
133                 sprintf(qbuf,"-----%s已下线-----\n",msg.name);
134                 Linklist s=head;
135                 while(s->next!=NULL)
136                 {
137                     sendto(sfd,qbuf,sizeof(qbuf),0,(struct sockaddr*)&cin,socklen);
138                     s=s->next;
139                 }
140             }
141         }
142     }
143     else
144     {
145         perror("pid error");
146         return -1;
147     }
148     //4、关闭套接字
149     close(sfd);
150     return 0;
151 }

客户端

  1 #include
  2 struct Msg
  3 {
  4     char type;
  5     char name[20];
  6     char text[100];
  7 };                                                                                                                                                                                                                                                              
  8 int main(int argc, const char *argv[])
  9 {
 10     if(argc!=3)
 11     {
 12         printf("请输入ip地址和端口号\n");
 13         return -1;
 14     }
 15     //创建用于通信的套接字文件描述符
 16     int cfd = socket(AF_INET, SOCK_DGRAM, 0);
 17     if(cfd == -1)
 18     {
 19         perror("socket error");
 20         return -1;
 21     }
 22     //填充服务器的地址信息结构体
 23     struct sockaddr_in sin;
 24     sin.sin_family = AF_INET;
 25     sin.sin_port = htons(argv[2]);
 26     sin.sin_addr.s_addr = inet_addr(argv[1]);
 27     struct Msg msg;
 28     char user[20]="";
 29     memset(&msg,0,sizeof(msg));
 30     printf("用户名:");
 31     fgets(user,sizeof(user),stdin);
 32     strcpy(msg.name,user);
 33     msg.type='L';
 34     sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
 35     pid_t pid=fork();
 36     //发送数据
 37     if(pid>0)
 38     {
 39         while(1)
 40         {
 41             fgets(msg.text,sizeof(msg.text),stdin);
 42             msg.text[strlen(msg.text)-1]='\0';
 43             msg.type='C';
 44             if((sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin)))==-1)
 45             {
 46                 perror("sendto error");
 47                 return -1;
 48             }
 49             if(strcpy(msg.text,"quit")==0)
 50             {
 51                 msg.type='Q';
 52                 sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
 53                 goto END;
 54             }
 55         }
 56     }
 57     //接受数据
 58     else if(pid==0)
 59     {
 60         while(1)
 61         {
 62             memset(&msg,0,sizeof(msg));
 63             if((recvfrom(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin)))==-1)
 64             {
 65                 perror("recvfrom error");
 66                 return -1;
 67             }
 68             if(msg.type=='L')
 69             {
 70                 printf("[%s]上线了\n",msg.name);
 71             }
 72             if(msg.type=='C')
 73             {
 74                 printf("[%s]:%s\n",msg.name,msg.text);
 75             }
 76             if(msg.type=='Q')
 77             {
 78                 printf("[%s]下线了\n",msg.name);
 79             }
 80         }
 81     }
 82     else
 83     {
 84         perror("pid error");
 85         return -1;
 86     }
 87 END:
 88     //关闭套接字
 89     close(cfd);
 90     return 0;
 91 }

你可能感兴趣的:(笔记)