zoukankan      html  css  js  c++  java
  • linux网络多线程编程实例

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


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

  • 相关阅读:
    java做微信支付notify_url异步通知服务端的写法
    QT如何编译出带调试信息的qtwebkit库
    Vmware 占用宿主机硬盘空间只增不减
    vmware linux无法正常上网
    Linux中find常见用法示例
    计算机网络OSI参考模型与tcp/ip四层模型
    Core开发-后台任务利器Hangfire使用
    Azure构建PredictionIO和Spark的推荐引擎服务
    NET MVC+EF6+Bootstrap
    服务器
  • 原文地址:https://www.cnblogs.com/buffer/p/1488601.html
Copyright © 2011-2022 走看看