用的是UDP方式。
服务器能同时接受十个客户端,各个客户端可以相互点对点通讯;可以对所有连到
服务器的客户端广播;也可以和服务器通讯。服务器也可以广播。
运行时你要先看懂源代码中的命令: "/w " 广播 ; "/s n " 对某个客户端; "/sv "对服务器;
命令是引号中的部分,注意空格。
服务端代码:
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <pthread.h>
#define PORT 8889
#define max_size 256
/////////////////////////////////////////////////////////
int sockfd,sockfd2[10],ret,i=0,j,flag=0;
struct sockaddr_in addr;
struct sockaddr_in addr2[10];
int unsigned addr_len =sizeof(struct sockaddr_in);
char inbuffer[256];
char outbuffer[256];
//char tempbuffer[256];
//int name[1];
void threads1();
void threads2();
///////////////////////////////////////////////////////
int main()
{
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{ perror("socket");
exit(1);
}
bzero(&addr,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr))<0)
{
perror("connect");
exit(1);
}
pthread_t ids1;
ret=pthread_create(&ids1,NULL,(void *) &threads1,NULL);
if(ret!=0)
{
printf("绾跨▼鍒涘缓澶辫触\n");
exit(1);
}
pthread_t ids2;
ret=pthread_create(&ids2,NULL,(void *) &threads2,NULL);
if(ret!=0)
{
printf("绾跨▼鍒涘缓澶辫触\n");
exit(1);
}
pthread_join(ids1,NULL);
pthread_join(ids2,NULL);
close (sockfd);
return 1;
}
////////////////////////////////////////////////////////////
void threads1(void)
{
for(;
{
bzero(outbuffer,sizeof(outbuffer));
read(STDIN_FILENO,outbuffer,sizeof(outbuffer));
if(strncmp(outbuffer,"/w ",3)==0)//大家 说
{
strcat(outbuffer,"server said: ");
if(addr2[0].sin_port!=0)
{
for(j=0;j<=9;j++)
{
if(addr2[j].sin_port!=0)//////////////////////////转发给别的客户端
{
sendto(sockfd2[j],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[j],addr_len);
perror("sendto");
}
}
}else{
printf("no clent \n");
}
}
else if(strncmp(outbuffer,"/s ",3)==0)////////////////////对某个客户端说
{
if(strncmp(outbuffer,"/s 0 ",5)==0)
{
sendto(sockfd2[0],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[0],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 1 ",5)==0)
{
sendto(sockfd2[1],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[1],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 2 ",5)==0)
{
sendto(sockfd2[2],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[2],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 3 ",5)==0)
{
sendto(sockfd2[3],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[3],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 4 ",5)==0)
{
sendto(sockfd2[4],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[4],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 5 ",5)==0)
{
sendto(sockfd2[5],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[5],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 6 ",5)==0)
{
sendto(sockfd2[6],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[6],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 7 ",5)==0)
{
sendto(sockfd2[7],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[7],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 8 ",5)==0)
{
sendto(sockfd2[8],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[8],addr_len);
perror("sendto");
}
else if(strncmp(outbuffer,"/s 9 ",5)==0)
{
sendto(sockfd2[9],outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr2[9],addr_len);
perror("sendto");
}
}
else{
printf("error message!\n");
}
}
}
////////////////////////////////////////////////////////////
void threads2(void)
{
for(j=0;j<=9;j++)
{
addr2[j].sin_family=AF_INET;
addr2[j].sin_addr.s_addr=0;
addr2[j].sin_port=0;
}
for(;{
bzero(inbuffer,sizeof(inbuffer));
recvfrom(sockfd,inbuffer,sizeof(inbuffer),0,(struct sockaddr*)&addr,&addr_len);
printf("receive from clent-->%s",inbuffer);
for(j=0;j<=9;j++)
{
if(addr.sin_port==addr2[j].sin_port)flag=flag+1;//////////////////////判断 该客户端是否已经登录
}
if(flag==0)///////////////////// 如果没有就 记录
{
sockfd2[i]=sockfd;
addr2[i].sin_port=addr.sin_port;
addr2[i].sin_addr.s_addr=addr.sin_addr.s_addr;
if(i==9)i=0;
i=i+1;
}
flag=0;
/////////////////////////////////下面 做发送前处理
if(strncmp(inbuffer,"/w ",3)==0)//对 大家 说
{
strcat(inbuffer,"a clent said to everone");
if(addr2[0].sin_port!=0)
{
for(j=0;j<=9;j++)
{
if(addr2[j].sin_port!=0&&addr2[j].sin_port!=addr.sin_port)//////////////////////////转发给别的客户端
{
sendto(sockfd2[j],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[j],addr_len);
perror("sendto");
}
}
}
}
else if(strncmp(inbuffer,"/s ",3)==0)////////////////////对某个客户端说
{
if(strncmp(inbuffer,"/s 0 ",5)==0)
{
sendto(sockfd2[0],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[0],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 1 ",5)==0)
{
sendto(sockfd2[1],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[1],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 2 ",5)==0)
{
sendto(sockfd2[2],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[2],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 3 ",5)==0)
{
sendto(sockfd2[3],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[3],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 4 ",5)==0)
{
sendto(sockfd2[4],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[4],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 5 ",5)==0)
{
sendto(sockfd2[5],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[5],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 6 ",5)==0)
{
sendto(sockfd2[6],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[6],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 7 ",5)==0)
{
sendto(sockfd2[7],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[7],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 8 ",5)==0)
{
sendto(sockfd2[8],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[8],addr_len);
perror("sendto");
}
else if(strncmp(inbuffer,"/s 9 ",5)==0)
{
sendto(sockfd2[9],inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr2[9],addr_len);
perror("sendto");
}
}
else if(strncmp(inbuffer,"/sv ",4)==0)//对 大家 说
{
printf("clent to server \n");
}
else{
bzero(inbuffer,sizeof(inbuffer));
strcpy(inbuffer,"the message error!");
sendto(sockfd,inbuffer,strlen(inbuffer),0,(struct sockaddr*)&addr,addr_len);/////如果 消息格式不对 告诉该客户端
perror("sendto");
}
}
}
----------------------------------------------------------------------------------------------------------------
客户端代码:
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define PORT 8889
#define max_size 256
#define SERVER_IP "127.0.0.1"
/////////////////////////////////////////////////
int sockfd;
struct sockaddr_in addr;
int unsigned addr_len =sizeof(struct sockaddr_in);
char inbuffer[256];
char outbuffer[256];
///////////////////////////////////////////////////
void threads1();
void threads2();
int main(void)
{
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
perror("socket");
exit(1);
}
bzero(&addr,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr=inet_addr(SERVER_IP);
pthread_t ids1;
pthread_t ids2;
if(pthread_create(&ids1,NULL,(void *) & threads1,NULL)!=0)
{
printf("线程创建错误\n");
exit(1);
}
//pthread_mutex_init (&mutex,NULL);
if(pthread_create(&ids2,NULL,(void *) & threads2,NULL)!=0)
{
printf("线程创建错误\n");
exit(1);
}
pthread_join(ids1,NULL);
pthread_join(ids2,NULL);
close(sockfd);
return 1;
}
///////////////////////////////////////////////////////////
void threads1()
{
for(;;){
bzero(outbuffer,sizeof(outbuffer));
fgets(outbuffer,max_size,stdin);
sendto(sockfd,outbuffer,strlen(outbuffer),0,(struct sockaddr*)&addr,addr_len);
}
}
void threads2()
{
for(;;){
bzero(inbuffer,sizeof(inbuffer));
recvfrom(sockfd,inbuffer,sizeof(inbuffer),0,(struct sockaddr*)&addr,&addr_len);
printf("receive from server-->:%s \n",inbuffer);
}
}
大家小心,源码里面的符号可能被当成转义.
如果编译有错,请自己添加上符号