2019独角兽企业重金招聘Python工程师标准>>>
客户端:子进程发送信息父进程接受信息
服务器:子进程发送广播信息,父进程接受信息
client.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define N 128
typedef struct
{
char type;
char name[32];
char text[N];
}MSG;
int main(int argc,char *argv[])
{
int socketfd;
socklen_t addr_len;
pid_t pid;
MSG msg;
struct sockaddr_in server_addr;
if(argc < 3)
{
printf("uasge: %s ip port\n",argv[0]);
exit(-1);
}
if((socketfd = socket(PF_INET,SOCK_DGRAM,0)) < 0)
{
perror("socket");
exit(-1);
}
printf("input name:\n");
fgets(msg.name,64,stdin);
msg.name[strlen(msg.name) - 1] = '\0';
msg.type='L';
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
addr_len = sizeof(server_addr);
if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&server_addr,addr_len) < 0)
{
perror("sendto3");
exit(-1);
}
if((pid = fork()) == -1 )
{
perror("fork");
exit(-1);
}
if(pid == 0)
{
while(1)
{
fgets(msg.text,N,stdin);
msg.text[strlen(msg.text) - 1] = '\0';
if(strncmp(msg.text,"quit",4) == 0)
{
msg.type = 'Q';
if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&server_addr,addr_len) < 0)
{
perror("sendto2");
exit(-1);
}
kill(getppid(),SIGKILL);
break;
}
else
{
msg.type='B';
if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&server_addr,addr_len) < 0)
{
perror("sendto1");
exit(-1);
}
}
}
close(socketfd);
}
if(pid > 0)
{
while(1)
{
if(recvfrom(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&server_addr,&addr_len) < 0)
{
perror("recvfrom");
exit(-1);
}
switch(msg.type)
{
case 'L':
printf("%s login\n",msg.name);
break;
case 'B':
printf("from %s> %s\n",msg.name,msg.text);
break;
case 'Q':
printf("%s quit\n",msg.name);
break;
}
}
}
return 0;
}
server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define N 128
#define L 1
#define B 2
#define Q 3
typedef struct
{
char type;
char name[32];
char text[N];
}MSG;
typedef struct node
{
struct sockaddr_in addr;
struct node *next;
}listnode,*linklist;
linklist linklist_create()
{
linklist H;
H = (linklist)malloc(sizeof(listnode));
memset(H,0,sizeof(listnode));
H->next = NULL;
return H;
}
void insert_data(linklist H,struct sockaddr_in client_addr)
{
linklist p = NULL;
p =(linklist)malloc(sizeof(listnode));
p->addr = client_addr;
p->next = H->next;
H->next = p;
return ;
}
void process_login(int socketfd,linklist H,MSG msg,struct sockaddr_in client_addr)
{
insert_data(H,client_addr);
linklist h1 = H;
while(h1->next != NULL)
{
h1 = h1->next;
if(memcmp(&client_addr,&h1->addr,sizeof(client_addr)) != 0 )
{
if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&(h1->addr),sizeof(h1->addr)) < 0)
{
perror("sendto4");
exit(-1);
}
}
}
return ;
}
void process_broadcast(int socketfd,linklist H,MSG msg,struct sockaddr_in client_addr)
{
linklist h1 = H;
while(h1->next != NULL)
{
h1 = h1->next;
if(memcmp(&client_addr,&h1->addr,sizeof(client_addr)) != 0)
{
if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&(h1->addr),sizeof(h1->addr)) < 0)
{
perror("sendto3");
exit(-1);
}
}
}
return ;
}
void process_quit(int socketfd,linklist H,MSG msg,struct sockaddr_in client_addr)
{
linklist p = H;
linklist q;
while(p->next)
{
if(memcmp(&client_addr,&p->next->addr,sizeof(client_addr)) == 0)
{
q = p->next;
p->next = q->next;
free(q);
q = NULL;
}
else
{
if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&p->next->addr,sizeof(p->next->addr)) < 0)
{
perror("sendto");
exit(-1);
}
p = p->next;
}
}
return ;
}
int main(int argc,char *argv[])
{
int socketfd;
socklen_t addr_len;
pid_t pid;
MSG msg;
struct sockaddr_in server_addr,client_addr;
if(argc < 3)
{
printf("uasge: %s ip port\n",argv[0]);
exit(-1);
}
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
if((socketfd = socket(PF_INET,SOCK_DGRAM,0)) < 0)
{
perror("socket");
exit(-1);
}
if(bind(socketfd,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0)
{
perror("bind");
exit(-1);
}
addr_len = sizeof(client_addr);
linklist H = linklist_create();
if((pid = fork()) == -1)
{
perror("fork");
exit(-1);
}
if(pid == 0)
{
while(1)
{
fgets(msg.text,N,stdin);
msg.text[strlen(msg.text)-1] = '\0';
strcpy(msg.name,"server");
msg.type = 'B';
if(sendto(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0)
{
perror("sendto1");
close(socketfd);
exit(-1);
}
}
}
else if(pid > 0)
{
while(1)
{
if(recvfrom(socketfd,&msg,sizeof(msg),0,(struct sockaddr*)&client_addr,&addr_len) < 0)
{
perror("recvfrom");
close(socketfd);
exit(-1);
}
switch(msg.type)
{
case 'L':
process_login(socketfd,H,msg,client_addr);
break;
case 'B':
process_broadcast(socketfd,H,msg,client_addr);
break;
case 'Q':
process_quit(socketfd,H,msg,client_addr);
break;
}
}
}
return 0;
}
运行时须带两个参数 第一个是ip 第二个是端口
程序流程图及主要结构体
typedef struct msg
{
char type; //消息类型
char name[N]; //客户名称
char text[N]; //消息正文
}MSG;
typedef struct node //存放客户端的IP的链表
{
struct sockaddr_in addr;
struct node *next;
}listnode, *linklist;