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\n",

                         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\n", 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\n",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) |
给主人留下些什么吧!~~
评论热议
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值