利用UDP编写服务器广播多个客户端程序。
1、服务器的搭建
(1)、创建UDP端口:
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
len = sizeof(cetaddr);
addr.sin_family = AF_INET;
addr.sin_port = htons(6666);
addr.sin_addr.s_addr = inet_addr("0");
ret = bind(sockfd,(struct sockaddr *)&addr,sizeof(addr));
if(-1 == ret)
{
perror("bind");
exit(-1);
}
(2)、记录连接服务器的客户端及其相关信息,并转发消息给除发送者以外的全部客户端
ret = recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&cetaddr,&len);
for(i = 0;ntohs(usr[i].sin_port) != 0;i++)
{
if(usr[i].sin_port == cetaddr.sin_port)
{
flag = 1;
continue;
}
else
{
others = cetaddr;
others.sin_port = usr[i].sin_port;
sendto(sockfd,buf,ret,0,(struct sockaddr *)&others,len);
}
}
if(i > 127)
{
printf("clinet full\n");
}
else if(flag == 0)
{
usr[i] = cetaddr;
}
else
flag = 0;
}
2、客户端代码
void *recv_msg(void *argv)
{
int sockfd = (int )argv;
char buf[64];
while(1)
{
recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);
printf("recv:%s\n",buf);
}
}
int main(int argc,char **argv)
{
struct sockaddr_in addr,cetaddr;
int ret,len;
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
char buf[128];
pthread_t pid;
if(argc < 2)
{
printf("usage:%s \n",argv[0]);
exit(-1);
}
len = sizeof(cetaddr);
addr.sin_family = AF_INET;
addr.sin_port = htons(6666);
addr.sin_addr.s_addr = inet_addr(argv[1]);
while(1)
{
fgets(buf,sizeof(buf),stdin);
ret = sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&addr,sizeof(addr));
pthread_create(&pid,NULL,recv_msg,(void *)sockfd);
}
return 0;
}
为保证接收的实时性,客户端用创建了一个新的线程来接收服务器发送过来的消息。
此代码是在虚拟机的几个终端里进行测试,每一个客户终端都需要先向服务器发送一条消息后才能收到其他客户终端发过来的消息,且第一条消息也不会同步到其他客户终端。