服务器
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<unistd.h>
#define A 1 //登录
#define B 2 //聊天
#define C 3 //退出
#define M 1024
typedef struct{
int type;
char data[M];
char name[20];
}MSG;
typedef struct node{
strcut sockaddr_in addr;
struct node *next;
}linknode, *linklist;
void do_login(int sockfd,linklist H,struct sockaddr_in caddr, MSG* msg);
void do_chat(int sockfd,linklist H,struct sockaddr_in caddr, MSG *msg);
void do_quit(int sockfd, linklist H,struct sockaddr_in caddr, MSG *msg);
linklist create_linklist(){
linklist H = (linklist)malloc(linknode); //创建用户列表
if(NULL == H){
perror("malloc");
return NULL;
}
H->next = NULL;
return H;
}
int main()
{
MSG msg;
linklist H;
pid_t pid;
int sockfd = socket(AF_INET, SOCK_DGRAM,0);
if(sockfd < 0){
perror("socket");
exit(-1);
}
printf("socket is success,,\n") ;
struct sockfdaddr_in caddr,saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htos(7777);
saddr.sin_addr.s.addr = inet_addr("127.0.0.1");
int s_len = sizeof(saddr);
int c_len = sizeof(caddr);
int ret = bind(sockfd,(struct sockaddr *)&saddr,s_len);
if(ret < 0){
perror("bind");
exit(-1);
}
printf("bind is success \n");
pid = fork();
if(pid < 0)
{
perror("fork");
exit(-1);
}
else if(pid == 0)
{
bzero(&msg, sizeof(MSG));
strcopy(msg.name,"sever");
msg.type = B;
while(1){
fgets(msg.data,M, stdin);
msg.data[strlen(msg.data)-1] = '\0';
sendto(scokfd,&msg,sizeof(MSG),0,(struct sockaddr *)&caddr,c_len); //服务器发消息,子进程发给父进程,再由父进程发给客户端
}
}
else
{
H = create_linklist();
while(1)
{
recvfrom(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&caddr,&c_len); //父进程接收客户端消息,在发给其他客户端
switch(msg.type)
{
case A:
do_login(sockfd, H, caddr, &msg);
break;
case B:
do_chat(sockfd,H, caddr , &msg);
break;
case C:
do_quit(sockfd, H,caddr,&msg);
break;
default:
puts("erro...");
break;
}
}
}
return 0;
}
void do_login(int sockfd, linklist H, struct sockaddr_in caddr, MSG*msg)
{
linklist q;
sprintf(msg->data,"%s login....",msg->name);
int c_len = sizeof(caddr);
q = (linklist)malloc(sizeof(linknode));
if(NULL == q)
{
perror("malloc");
exit(-1);
}
q->addr = caddr;
q->next = H->next;
H->next = q;
linklist p = H->next;
while(p)
{
sendto(sockfd,msg,sizeof(MSG),0,(struct sockaddr *)&caddr,c_len);
p = p->next;
}
printf("%s \n",msg->data);
}
void do_chat(int sockfd,,linklist H, struct sockaddr_in addr, MSG* msg )
{
char buf[M] = {0};
sprintf(buf,"%s said : %s",msg->name,msg->data);
strcpy(msg->data,buf);
int c_len = sizeof(caddr);
linklist p = H->next;
while(p)
{
if(memcmp(&caddr,&p->addr,c_len) != 0)
{
sendto(sockfd,msg,sizeof(MSG),0,(struct sockaddr *)&caddr,c_len);
}
p = p->next;
}
puts(msg->data);
}
void do_quit(int sockfd,,linklist H, struct sockaddr_in addr, MSG* msg )
{
sprintf(msg->data,"%s .quit...",msg->name);
int c_len = sizeof(caddr);
linklist p = H;
linklist q;
while(p->next)
{
if(memsmp(&caddr,&p->next->addr,c_len) ==0)
{
q = p->next;
p->next = q->next;
free(q);
q = NULL;
}
else
{
sendto(sockfd,msg,sizeof(MSG),0,(struct sockadddr *)&caddr,c_len);
p = p->next;
}
}
puts(msg->data);
}
客户端
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<signal.h>
#define A 1 //登录
#define B 2 //聊天
#define C 3 //退出
#define M 1024
typedef struct{
int type;
char data[M];
char name[20];
}MSG;
int main()
{
MSG msg;
pid_t pid;
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd <0)
{
perror("socket");
exit(-1);
}
printf("socket %d is success...\n",sockfd);
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(9998);
saddr.sin_addr.s_addr = inet_addr("192.168.91.131");
int s_len = sizeof(saddr);
//memset(&saddr,0,s_len);
//登录
puts("***************开始登录***********");
msg.type = A;
puts("输入的你的名字:");
fgets(msg.name,20,stdin);
msg.name[strlen(msg.name)-1] = '\0';
int ret = sendto(sockfd, &msg,sizeof(MSG),0,(struct sockaddr *)&saddr,s_len);
if(ret < 0)
{
perror("sendto");
exit(-1);
}
pid = fork();
if(pid<0)
{
perror("fork");
exit(-1);
}
else if(pid == 0) //子进程发送消息
{
printf("进入聊天室..\n");
while(1)
{
fgets(msg.data,M,stdin);
msg.data[strlen(msg.data)-1] = '\0';
if(strcmp(msg.data, "quit") == 0)//退出
{
msg.type = C;
sendto(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&saddr,s_len);
close(sockfd);
kill(getppid(), SIGKILL);
exit(0);
}
else // 聊天
{
msg.type = B;
sendto(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&saddr,s_len);
}
}
}
else // 父进程接受消息
{
while(1)
{
recvfrom(sockfd,&msg,sizeof(MSG),0,(struct sockaddr *)&saddr,&s_len);
printf("%s\n",msg.data);
}
}
return 0;
}