linux网络多线程编程实例

让人想犯罪 __ 提交于 2020-02-24 14:43:06

用的是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);
}
}


大家小心,源码里面的符号可能被当成转义.
如果编译有错,请自己添加上符号

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!