基于 TCP 协议的并发服务器程序

服务端:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <netdb.h>
#include <pthread.h>

//线程执行函数,负责读写
void *thr_fn ( void *arg )
{
    int size, j;
    char recv_buf[1024];
    int *parg = ( int * ) arg;
    int new_fd = *parg;

    while ( ( size = read ( new_fd, recv_buf, sizeof ( recv_buf ) ) ) > 0 ) {
        if ( recv_buf[0] == '@' ) {
            break;
        }

        printf ( "Message from client(%d): %s\n", size, recv_buf );

        for ( j = 0; j < size; ++j )
            recv_buf[j] = toupper(recv_buf[j]);
        write(new_fd,recv_buf,size);
        }
        close(new_fd);
        return 0;
}

int main(int argc, char *argv[]){
   socklen_t clt_addr_len;
    int listen_fd;
    int com_fd;
    int ret;
    int i;
    static char recv_buf[1024];
    int len;
    int port;
    pthread_t tid;

    struct sockaddr_in clt_addr;
    struct sockaddr_in srv_addr;
    //服务器端运行时要给出端口信息,该端口为监听端口
    if(argc != 2){
        printf("Usage:%s port\n",argv[0]);
        return -1;
    }

    //获得输入的端口
    port = atoi(argv[1]);

    //创建套接字用于服务器的监听
    listen_fd = socket(PF_INET,SOCK_STREAM,0);
    if(listen_fd < 0){
        perror("cannot create listening socket");
        return -1;
    }

    //填充关于服务器的套接字信息
    memset(&srv_addr,0,sizeof(srv_addr));
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    srv_addr.sin_port = htons(port);

    //将服务器和套接字绑定
    ret = bind(listen_fd,(struct sockaddr *)&srv_addr,sizeof(srv_addr));
    if(ret == -1){
        perror("cannot bind server socket");
        close(listen_fd);
        return -1;
    }

    //监听指定端口
    ret = listen(listen_fd,5);
    if(ret == -1){
        perror("cannot listen the client connect request");
        close(listen_fd);
        return -1;
    }

    /*
        对每个连接来的客户端创建一个线程,单独与其进行通信,
        首先调用 read 函数读取客户端发送来的信息
        将其转化成大写后发送回客户端
        当输入"@"时,程序退出
    */
    while(1){
        len = sizeof(clt_addr);
        com_fd = accept(listen_fd,(struct sockaddr *)&clt_addr,&len);
        if(com_fd < 0){
            if(errno == EINTR)
                continue;
            else{
                perror("cannot accept client connect request");
                close(listen_fd);
                return -1;
            }
        }
        printf("com_fd = %d\n",com_fd); //打印建立连接的客户端产生的套接字
        if((pthread_create(&tid,NULL,thr_fn,&com_fd)) == -1){
            perror("pthread_create error");
            close(listen_fd);
            close(com_fd);
            return -1;
        }
    }
    return 0;
}

客户端:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <unistd.h>

int main(int argc, char**argv){
    int connect_fd;
    int ret;
    char snd_buf[1024];
    int i;
    int port;
    int len;
    static struct sockaddr_in srv_addr;
    //客户端运行需要给出具体的连接地址和端口
    if(argc != 3){
        printf("Usage: %s server_ip_address port\n",argv[0]);
        return -1;
    }
    //获得输入的端口
    port = atoi(argv[2]);

    //创建套接字用于客户端的连接
    connect_fd = socket(PF_INET,SOCK_STREAM,0);
    if(connect_fd < 0)
    {
        perror("cannot create communication socket");
        return 1;
    }

    //填充关于服务器的套接字信息
    memset(&srv_addr,0,sizeof(srv_addr));
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = inet_addr(argv[1]);
    srv_addr.sin_port = htons(port);

    //连接指定的服务器
    ret = connect(connect_fd,(struct sockaddr *)&srv_addr,sizeof(srv_addr));
    if(ret == -1){
        perror("cannot connect to the server");
        close(connect_fd);
           return -1;
    }

    memset(snd_buf,0,1024);

    /*
        用户输入信息后,程序将输入的信息通过套接字发送给服务器,
        然后调用read函数从服务器中读取发送来的信息
        当输入"@"时,程序退出
    */
    while(1){
        write(STDOUT_FILENO,"input message:", 14);
        len = read(STDIN_FILENO,snd_buf,1024);
        if(len > 0)
            write(connect_fd,snd_buf,len);

        len = read(connect_fd,snd_buf,len);
        if(len > 0)
            printf("Message form server: %s\n",snd_buf);
        if(snd_buf[0] == '@')
            break;
    }
    close(connect_fd);
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值