| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1235 人关注过本帖
标题:求修改c语言 多线程server 代码!!
只看楼主 加入收藏
kuvk
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2016-7-14
结帖率:0
收藏
已结贴  问题点数:10 回复次数:1 
求修改c语言 多线程server 代码!!
   最近写了一个Linux环境下的C语言代码,目的是用线程实现并行四则运算server。期待的效果是多个client把运算参数和运算符号传给server,server接收多个运算请求并运用线程分别计算,把结果返回给相应的client。   但是实际执行时从client1先发出运算请求,然后client2发出运算请求,server可以接收两个请求,但server算出client1的结果并返回给client1后就跳出循环,关闭socket了,返回给client2结果永远是0。想问问各位大神代码错误出在哪?应该怎么修改使之实现并行运算并正确返回结果。

server代码

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#define SUCCESS 0
#define ERROR   1

#define SERVER_PORT 1600
#define MAX_MSG 256


int server;         /* listening socket descriptor */


/**
 * cleanup() is called to kill the thread upon SIGINT.
**/
void cleanup()
{
    close(server);
    pthread_exit(NULL);
    return;
} /* cleanup() */


/**
 * Thread handler for incoming connections...
**/
void handler(void * paramsd) {
    struct sockaddr_in cliAddr;
    int client_local;   /* keep a local copy of the client's socket descriptor */
    int addr_len;       /* used to store length (size) of sockaddr_in */

    int ch[4];

    client_local = *((int *)paramsd); /* store client socket descriptor */
    addr_len = sizeof(cliAddr); /* store value of size of sockaddr_in */
    /* get clients name and store in cliAddr */
    getpeername(client_local, (struct sockaddr*)&cliAddr, &addr_len);   
    /* reset line */
        
    read(client_local,ch,sizeof(ch));    /* now read lines from the client socket */

    while(1)  /* loop - read from socket */
    {
        if (ch[1]==1){
        ch[3]=ch[0]+ch[2];
        }else if(ch[1]==2){
        ch[3]=ch[0]-ch[2];
        }else if(ch[1]==3){
        ch[3]=ch[0]*ch[2];
        }else if(ch[1]==4){
        ch[3]=ch[0]/ch[2];
        }
  

        send(client_local, ch,sizeof(ch),0);               
              
    }
   
    close(client_local);        
    return;
} /* handler() */

/* main function */
int main (int argc, char *argv[])
{
    int client;         /* client socket descriptor */
    int addr_len;       /* used to store length (size) of sockaddr_in */
    pthread_t thread;   /* thread variable */
   
    struct sockaddr_in cliAddr;   /* socket address for client */
    struct sockaddr_in servAddr;  /* socket address for server */

    signal(SIGINT, cleanup);      /* now handle SIGTERM and SIGINT */   
    signal(SIGTERM, cleanup);
  
    /* now create the server socket
       make it an IPV4 socket (PF_INET) and stream socket (TCP)
       and 0 to select default protocol type */         
    server = socket(PF_INET, SOCK_STREAM, 0);
    if (server < 0) {
        perror("cannot open socket ");
        return ERROR;
    }
  
    /* now fill in values of the server sockaddr_in struct
       s_addr and sin_port are in Network Byte Order (Big Endian)
       Since Intel CPUs use Host Byte Order (Little Endian), conversion
       is necessary (e.g. htons(), and htonl() */   
    servAddr.sin_family = AF_INET;  /* again ipv4 */  
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* local address */
    servAddr.sin_port = htons(SERVER_PORT);
    memset(servAddr.sin_zero, 0, 8);
        
    /* now bind server port
       associate socket (server) with IP address:port (servAddr) */
    if (bind(server, (struct sockaddr *) &servAddr, sizeof(struct sockaddr)) < 0) {
        perror("cannot bind port ");
        return ERROR;
    }

    /* wait for connection from client with a pending queue of size 5 */
    listen(server, 5);
      
    while(1) /* infinite loop */
    {
        int ch[4];

        printf("%s: waiting for data on port TCP %u\n", argv[0], SERVER_PORT);
        addr_len = sizeof(cliAddr);
        
        /* new socket for client connection
           accept() will block until a connection is present
           accept will return a NEW socket for the incoming connection   
           server socket will continue listening
           store client address in cliAddr */
        client = accept(server, (struct sockaddr *) &cliAddr, &addr_len);
        if (client < 0) {
            perror("cannot accept connection ");
            break;
        }
   
        pthread_create(&thread, 0, (void*)&handler, (void*) &client);
    } /* while (1) */

    close(server);
    exit(0);
} /* main() */

client代码

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h> /* close */
#include <string.h>
#include <stdlib.h>

#define SERVER_PORT 1600
#define MAX_MSG 256

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

    int client;  /* client socket */
    int rc;   
    struct sockaddr_in local_addr, serv_addr;
    struct hostent * host;

    int ch[4];

    if(argc < 2) {
        printf("usage: %s <server>\n",argv[0]);
        exit(-1);
    }

    /* get host address from specified server name */
    host = gethostbyname(argv[1]);
  
    if (host == NULL)
    {
        printf("%s: unknown host '%s'\n",argv[0],argv[1]);
        exit(-1);
    }

    /* now fill in sockaddr_in for remote address */
    serv_addr.sin_family = host->h_addrtype;
    /* get first address in host, copy to serv_addr */
    memcpy((char *) &serv_addr.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
    serv_addr.sin_port = htons(SERVER_PORT);
    memset(serv_addr.sin_zero, 0, 8);

    /* create local stream socket */
    client = socket(PF_INET, SOCK_STREAM, 0);
    if (client < 0) {
        perror("cannot open socket ");
        exit(-1);
    }

    /* bind local socket to any port number */
    local_addr.sin_family = AF_INET;
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    local_addr.sin_port = htons(0);
    memset(local_addr.sin_zero, 0, 8);

    rc = bind(client, (struct sockaddr *) &local_addr, sizeof(local_addr));

    if (rc < 0)
    {
        printf("%s: cannot bind port TCP %u\n",argv[0],SERVER_PORT);
        perror("error ");
        exit(1);
    }
   
    /* connect to server */
    rc = connect(client, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    if (rc < 0)
    {
        perror("cannot connect ");
        exit(1);
    }
   
    printf("A=");
    scanf("%d",&ch[0]);
    printf("sign=(1=+,2=-,3=*,4=/)");
    scanf("%d",&ch[1]);
        printf("B=");
    scanf("%d",&ch[2]);

   
    rc = send(client,ch,sizeof(ch),0);
    if (rc < 0)
    {
        perror("cannot send data ");
        close(client);
        exit(-1);
    }
 
        read(client,ch,sizeof(ch));

    printf("answer= %d \n",ch[3]);
   
    close(client);   
    return 0;
  
} /* main() */
搜索更多相关主题的帖子: include server 多线程 c语言 C语言 
2016-07-14 18:55
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:10 

 while(1) /* infinite loop */
    {
        int ch[4];

        printf("%s: waiting for data on port TCP %u\n", argv[0], SERVER_PORT);
        addr_len = sizeof(cliAddr);
        
        /* new socket for client connection
           accept() will block until a connection is present
           accept will return a NEW socket for the incoming connection   
           server socket will continue listening
           store client address in cliAddr */
        client = accept(server, (struct sockaddr *) &cliAddr, &addr_len);
        if (client < 0) {
            试试这里:
            int err = 获取错误信息
            if (err == 为非阻塞,没有连接)
            {
                延时0.1秒
                continue;
            }
            else
            {            
                perror("cannot accept connection ");
                break;
            }
        }
   
        pthread_create(&thread, 0, (void*)&handler, (void*) &client);
    } /* while (1) */
2016-07-14 20:07
快速回复:求修改c语言 多线程server 代码!!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016561 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved