• server-client之间的通信 刘峰


    09嵌入式方向    计应(2)班           刘峰

    server-client之间的通信

    启动服务器程序,客户端把输入发给服务器,服务器再把数据发给其他客户端。客户端利用线程来实现,pthread_create()创建新线程,新线程用来显示buf中的数据,当前线程从pthread_create()返回往下继续执行,阻塞当前进程等待用户输入,并将输入保存到buf中。

    /*--------server.c----------------*/

    #include

    #include tdlib.h>

    #include

    #include

    #include "wrap.c"

    #define MAXLINE 80

    #define SERV_PORT 8000

     

    int main(int argc, char **argv)

    {

          int i, maxi, maxfd, listenfd, connfd, sockfd, xx;

          int nready, client[FD_SETSIZE];

          ssize_t n;

          fd_set rset, allset;

          char buf[MAXLINE];

          char str[INET_ADDRSTRLEN];

          socklen_t cliaddr_len;

          struct sockaddr_in      cliaddr, servaddr;

     

          listenfd = Socket(AF_INET, SOCK_STREAM, 0);

     

          bzero(&servaddr, sizeof(servaddr));

          servaddr.sin_family      = AF_INET;

          servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

          servaddr.sin_port        = htons(SERV_PORT);

     

          Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

     

          Listen(listenfd, 20);

     

          maxfd = listenfd;            /* initialize */

          maxi = -1;                  /* index into client[] array */

          for (i = 0; i < FD_SETSIZE; i++)

                client[i] = -1;      /* -1 indicates available entry */

          FD_ZERO(&allset);

          FD_SET(listenfd, &allset);

     

          for ( ; ; ) {

                rset = allset;      /* structure assignment */

                nready = select(maxfd+1, &rset, NULL, NULL, NULL);

                if (nready < 0)

                      perr_exit("select error");

     

                if (FD_ISSET(listenfd, &rset)) { /* new client connection */

                      cliaddr_len = sizeof(cliaddr);

                      connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);

     

                      printf("received from %s at PORT %d ",

                             inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),

                             ntohs(cliaddr.sin_port));

     

                      for (i = 0; i < FD_SETSIZE; i++)

                            if (client[i] < 0) {

                                  client[i] = connfd; /* save descriptor */

                                  break;

                            }

                      if (i == FD_SETSIZE) {

                            fputs("too many clients ", stderr);

                            exit(1);

                      }

     

                      FD_SET(connfd, &allset);      /* add new descriptor to set */

                      if (connfd > maxfd)

                            maxfd = connfd; /* for select */

                      if (i > maxi)

                            maxi = i;      /* max index in client[] array */

     

                      if (--nready == 0)

                            continue;      /* no more readable descriptors */

                }

     

                for (i = 0; i <= maxi; i++) {      /* check all clients for data */

                      if ( (sockfd = client[i]) < 0)

                            continue;

                      if (FD_ISSET(sockfd, &rset)) {

                            if ( (n = Read(sockfd, buf, MAXLINE)) == 0) { //读取客户端发送内容

                                  /* connection closed by client */

                                  Close(sockfd);  //读取失败关闭连接

                                  FD_CLR(sockfd, &allset);//清除文件描述符

                                  client[i] = -1;//客户端置-1

                            } else {

                                  xx=sockfd;

                                  int j;

                                 

                                     for (j = 0; j <= maxi; j++) {

                                        

                                        if (FD_ISSET(sockfd, &rset)) {//把读到的数据发送给每个客户端

                                              if(sockfd!=client[j])

                                              Write(client[j],buf,n);

                                        }

                                  }  

                                       

                            }

     

                            if (--nready == 0)

                                  break;      /* no more readable descriptors */

                      }

                }

          }

    }

    /*---------------client.c------------*/

    #include

    #include

    #include

    #include

    #include "wrap.c"

    #include

    #include

    #define MAXLINE 80

    #define SERV_PORT 8000

     pid_t pid;

     pthread_t ntid;

    pthread_t tid;

     int err;

    char buf[MAXLINE];

    int sockfd, n;

    void *thr_fn(sockfe)/*新线程执行*/

    {   

         tid=pthread_self(); //获得当前线程id

      if(tid>0){     //判断当前线程是否成功

          while (fgets(buf, MAXLINE, stdin) != NULL) {

                Write(sockfe, buf, strlen(buf));}//向客户端发数据

         

           }

      }   

    int main(int argc, char *argv[])

    {

          struct sockaddr_in servaddr;

         

     

          sockfd = Socket(AF_INET, SOCK_STREAM, 0);

     

          bzero(&servaddr, sizeof(servaddr));

          servaddr.sin_family = AF_INET;

          inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);

          servaddr.sin_port = htons(SERV_PORT);

       

          Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

           fcntl(sockfd,F_SETFL, O_NDELAY);

        pid=getpid(); //获得当前进程ID

        void *sockfe=(void*)sockfd; //类型转换

       err = pthread_create(&ntid,NULL,thr_fn,sockfe);/*创建线程*/

        if(err!=0){  

                   fprintf(stderr,"can't create thread:%s ",strerror(err));

                    exit(1);}   //失败退出

          if(pid!=0){  //当前进程执行成功

              while(1){

          n=Read(sockfd, buf, MAXLINE);  //向服务器接收数据

          

           if (n > 0)

            Write(STDOUT_FILENO, buf, n); }  //读到的数据写进标准输出

         

          }

      

       Close(sockfd);

          return 0;

        }

    执行过程如下:

    服务器端

    [root@localhost ~]# cd /root/Desktop/

    [root@localhost Desktop]# gcc -g server.c -o server

    [root@localhost Desktop]# ./server

    received from 127.0.0.1 at PORT 60464   //已连接服务器的客户端

    received from 127.0.0.1 at PORT 60465

    received from 127.0.0.1 at PORT 60466

    客户端1

    [root@localhost ~]# cd /root/Desktop/

    [root@localhost Desktop]# gcc -g client.c -o client -lpthread

    [root@localhost Desktop]# ./client

    hgjghj

    fgfdggg

    gagagagfgfg

    jjhjjh

    nnn

    客户端2

    [root@localhost ~]# cd /root/Desktop/

    [root@localhost Desktop]# gcc -g client.c -o client -lpthread

    [root@localhost Desktop]# ./client

    hgjghj

    fgfdggg

    gagagagfgfg

    jjhjjh

    nnn

    启动客户端3

    [root@localhost ~]# cd /root/Desktop/

    [root@localhost Desktop]# gcc -g client.c -o client -lpthread

    [root@localhost Desktop]# ./client

    gagagagfgfg

    jjhjjh

    nnn

     

         

    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(624) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    怎样才有资格被称为开源软件
    [翻译]开发Silverlight 2.0的自定义控件
    网上Silverlight项目收集
    Google 分析的基准化测试
    IIS 承载的WCF服务失败
    Lang.NET 2008 相关Session
    Silverlight 2.0 beta1 堆栈
    asp.net 性能调较
    SQL Server 2005 的nvarchar(max),varchar(max)来救火
    LINQPad
  • 原文地址:https://www.cnblogs.com/ztguang/p/12647550.html
Copyright © 2020-2023  润新知