zoukankan      html  css  js  c++  java
  • Linux以下基于TCP多线程聊天室(server)

        接上篇博文,本文是server端的实现,主要实现的功能,就是现实client的连接。转发client发送的消息。以及client掉线提示等功能,同一时候能够在这这上面扩展和TCP以及线程相关的功能木块。

    tcpreceive.h

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
    #ifndef TCPRECEIVE_H
    #define TCPRECEIVE_H
    #define BUFFSIZE 2048
    #define listen_max 5
    int cond;
    int rscond;
    typedef struct TCP_rcv_arg
    {
    char *local_addr;
    int tcp_port;
    }TCP_rcv_arg_t;
    void stop_handler(int signum);
    void *tcppackrecv(void *arg);
    #endif
    tcpreceive.c 

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
     100
     101
     102
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
    #include "tcpreceive.h"
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/ioctl.h>
    #include <sys/param.h>
    #include <arpa/inet.h>
    #include <errno.h>
    #include <signal.h>
    #include <fcntl.h>
    #include <ctype.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/mman.h>
    #include <pthread.h>
    void stop_handler(int sinnum)
    {
    cond = 0;
    rscond = 0;
    }
    void *tcppackrecv(void *arg)
    {
    int listen_fd,client_id,len = 1;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    int sin_size;
    fd_set master;
    fd_set read_fds;
    int fdmax,i,newfd,j;
    char buf[BUFFSIZE + 1];
    TCP_rcv_arg_t *rcv_arg = (TCP_rcv_arg_t *)arg;
    sin_size = sizeof(client_addr);
    if(-1 == (listen_fd = socket(AF_INET,SOCK_STREAM,0)))
    {
    fprintf(stderr,"Socket Error:%s ",strerror(errno));
    pthread_exit(NULL);
    }
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //server_addr.sin_addr.s_addr = inet_addr((*rcv_arg).local_addr);
    server_addr.sin_port = htons((*rcv_arg).tcp_port);
    setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&len,sizeof(len));
    if( -1 == bind(listen_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)))
    {
    fprintf(stderr,"Bind Error:%s ",strerror(errno));
    pthread_exit(NULL);
    }
    if(-1 == listen(listen_fd,listen_max))
    {
    fprintf(stderr,"Listen Error:%s ",strerror(errno));
    pthread_exit(NULL);
    }
    //printf("listen ok! ");
    FD_ZERO(&master);
    FD_ZERO(&read_fds);
    FD_SET(listen_fd,&master);
    fdmax = listen_fd;
    cond = 1;
    while(cond)
    {
    read_fds = master;
    if(-1 == select(fdmax+1,&read_fds,NULL,NULL,NULL))
    {
    fprintf(stderr,"Server Select Error:%s ",strerror(errno));
    pthread_exit(NULL);
    }
    for(i = 0;i <= fdmax;i++)
    {
    if(FD_ISSET(i,&read_fds))
    {
    if(i == listen_fd)
    {
    if(-1 == (newfd = accept(listen_fd,(struct sockaddr *)&client_addr,(socklen_t *)&sin_size)))
    {
    fprintf(stderr,"Accept Error:%s ",strerror(errno));
    }
    else
    {
    FD_SET(newfd,&master);
    if(newfd > fdmax)
    {
    fdmax = newfd;
    }
    sprintf(buf,"Your SocketID is:%d.",newfd);
    if(send(newfd,buf,21,0) < 0)
    {
    printf("Send Error! ");
    }
    printf("there is a new connection in,form %s,SocketID is %d. ",inet_ntoa(client_addr.sin_addr),newfd);
    }
    }
    else
    {
    sprintf(buf,"Form %2d: ",i);
    if((len = recv(i,buf + 9,BUFFSIZE - 10,0)) <= 0)
    {
    if(0 == len)
    {
    printf("SocketID %d has left! ",i);
    }
    else
    {
    perror("the recv() go end! ");
    }
    close(i);
    FD_CLR(i,&master);
    }
    else
    {
    len += 9;
    buf[len] = '';
    printf("%s ",buf);
    for(j = 0;j <= fdmax;j++)
    {
    if(FD_ISSET(j,&master) && j != listen_fd && j !=i)
    {
    if(-1 == send(j,buf,len,0))
    {
    perror("Send() error! ");
    }
    }
    }
    }
    }
    }
    }
    }
    pthread_exit(NULL);
    }
    server.c

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <errno.h>
    #include "tcpreceive.h"
    #define PORT 8888
    #define IP "192.168.1.220"
    int main()
    {
    pthread_t tid;
    pthread_t id;
    void *tret;
    TCP_rcv_arg_t rcv_arg;
    rcv_arg.tcp_port = PORT;
    rcv_arg.local_addr = IP;
    printf("the main process! ");
    int i= pthread_create(&tid,NULL,(void *)tcppackrecv,(void *)&rcv_arg);
    if( i != 0)
    {
    printf("Create pthread error! ");
    pthread_exit(NULL);
    }
    if (0 != pthread_join(tid, &tret))
    {
    printf("Join pthread error! ");
    }
    return 0;
    }
    为了大家编译方便,将Makefile也放上来:

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    all:
    gcc -c tcpsed.c
    ar cr libtcpsed.a tcpsed.o
    gcc -c tcpreceive.c
    ar cr libtcpreceive.a tcpreceive.o
    gcc -o server server.c -L. -ltcpreceive -lpthread
    gcc -o client client.c -L. -ltcpsed -lpthread
    clean:
    rm -rf *.o *.a server client

    CSDN上面源代码下载地址:

    http://download.csdn.net/detail/u012377333/8079943

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    all:
    gcc -c tcpsed.c
    ar cr libtcpsed.a tcpsed.o
    gcc -c tcpreceive.c
    ar cr libtcpreceive.a tcpreceive.o
    gcc -o server server.c -L. -ltcpreceive -lpthread
    gcc -o client client.c -L. -ltcpsed -lpthread
    clean:
    rm -rf *.o *.a server client
    微信扫一扫,关注我!

  • 相关阅读:
    Web后台框架 目录
    C++ 目录
    【花书笔记】线性代数
    【Python数据挖掘概念、方法与实践】
    【统计学习基础】2. Overview of Supervised Learning
    字节与16进制
    【西瓜书】线性模型
    MySQL入门经典
    【机器学习基石】感知机模型
    python:web应用程序
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/6851719.html
Copyright © 2011-2022 走看看