2012-04-27 80 views
0

我有以下代码:插座和线程用C

该文件是principal.c,它具有的功能主要和其他方法。

在main():

connectAll(&NUM_THREADS); 
printf("TOTAL clients that to connect %d\n",NUM_THREADS); 

pthread_t thread[NUM_THREADS]; 
pthread_attr_t attr; 

/* Initialize and set thread detached attribute */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
paramThread params[NUM_THREADS]; 

    for(t=0;t<NUM_THREADS;t++) 
    { 

    printf("What's IP [%s] to connected now? %d\n",regIPConnected[t].ip,regIPConnected[t].idSocket); 

    params[t].idSocket=regIPConnected[t].idSocket; 
    params[t].idThread=t; 

    rc = pthread_create(&(thread[t]), &attr,conectaThread, &(params[t])); 
    if (rc) 
    { 
     printf("ERROR; return code from pthread_create() is %d\n", rc); 
    } 
    }//END FOR 

    /* Free attribute and wait for the other threads */ 
    pthread_attr_destroy(&attr); 

    for(t=0; t<NUM_THREADS; t++) 
    { 
    rc = pthread_join(thread[t], &status); 
    if (rc<0) { 
     printf("ERROR; return code from pthread_join() is %d\n", rc); 
    } 
    printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status); 
    }//END FOR 

    printf("Main: program completed. Exiting.\n"); 
    pthread_exit(NULL); 
} 

void *conectaThread (void *arg){ 

    paramThread* params = (paramThread*) &arg; 

    int idSocket=params->idSocket; 
    long tid=params->idThread; 

    printf("Thread %ld starting...\n",tid); 
    printf ("ID SOCKET THREAD %d\n",idSocket); 
    while (1) /* Run forever */ 
    { 

    int state=readSocket(idSocket,"status\n"); 

... 
} 

paramThread的结构是:

typedef struct 
{ 
    int idSocket; 
    long idThread; 
    void (*pf)(int, long); 
} paramThread; 

而另一文件,名为socket.c中

int openSocketInet (char *servIP,unsigned short servPort) 
{ 
    int optval,statusSocket=0; 
    socklen_t optlen = sizeof(optval); 

    /* Create the socket, using TCP */ 

    socketClient = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 
    printf("OK/NOK socket %d",socketClient); 
    if (socketClient<0) 
    { 
    switch (errno) 
    { 

     /*differents cases of errno*/ 
     default: 
    perror("socket()"); 
    statusSocket= -1; 
    }//END SWITCH 
    }//END IF 


    /* Check the status for the keepalive option */ 
    if(getsockopt(socketClient, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0 && statusSocket==0) { 
    statusSocket=checkGET_SETSockOpt(socketClient,1); 
    printf("Error getsockopt() is %d\n",statusSocket); 
    }//END IF 

    printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF")); 

    int fl = fcntl(socketClient, F_GETFL); 
    fcntl(socketClient, F_SETFL, fl | O_NONBLOCK); 

    /* Set the option active */ 
    optval = 1; //-->TRUE 
    optlen = sizeof(optval); 

    if(setsockopt(socketClient, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0 && statusSocket==0) { 
    statusSocket=checkGET_SETSockOpt(socketClient,0); 
    printf("Error setsockopt() is %d\n",statusSocket); 
    }//END IF 

    printf("SO_KEEPALIVE set on socket\n"); 

    /* Check the status again */ 
    if(getsockopt(socketClient, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0 && statusSocket==0) { 
    statusSocket=checkGET_SETSockOpt(socketClient,1); 
    printf("Error getsockopt() is %d\n",statusSocket); 
    }//END IF 

    printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF")); 


    if (connect(socketClient, (struct sockaddr *)&addressServer, sizeof(addressServer)) < 0 && statusSocket==0) 
    { 
    switch (errno) 
    { 
     /*diffents cases of errno to connect()*/ 
     default: 
    perror("connect()"); 
    statusSocket= -1; 
    }//END SWITCH 
    }//END IF 

    /* Construct the server address structure */ 
    bzero(&addressServer, sizeof(addressServer)); /* Hay que poner todo a ceros */ 

    addressServer.sin_family = AF_INET;   /* Internet address family */ 
    addressServer.sin_port = htons(servPort); /* puerto en formato de red */ 

    /* dirección IP en formato de red */ 
    int errInetAton=inet_aton(servIP, &addressServer.sin_addr); 
    if (errInetAton<0 && statusSocket==0) 
    { 
    printf("Fail the conversion of IP\n",servIP); 
    perror("inet_aton() Motive"); 
    statusSocket= -1; 
    }//END IF 


    printf("The IP %s to connect with sock %d\n",servIP,socketClient); 

    //To return identify a socket or fail 
    if (statusSocket<0) 
    return statusSocket; 
    else 
    return socketClient; 

} 

当我跑的结果是:

 
socket(): Success --> to sock 3 
SO_KEEPALIVE is OFF 
SO_KEEPALIVE set on socket 
SO_KEEPALIVE is ON 
The IP x.x.x.x to connect with sock 3 
socket(): Illegal seek --> to sock 4 
SO_KEEPALIVE is OFF 
SO_KEEPALIVE set on socket 
SO_KEEPALIVE is ON 
The IP y.y.y.y to connect with sock 4 

我希望我能连接到不同的ip具有相同插座


谢谢,这个问题是另外一个:

What's IP [x.x.x.x] to connected now? 3 
What's IP [y.y.y.y] to connected now? 4 
What's IP [z.z.z.z] to connected now? 5 


Out for 
Thread 5 starting... 
ID SOCKET THREAD 5 
Method READ! Send to socket id [5] and data is '[status]' 
STATUS THREAD 0 
Thread 5 starting... 
ID SOCKET THREAD 5 
Method READ! Send to socket id [5] and data is '[status]' 
Thread 5 starting... 
ID SOCKET THREAD 5 
Method READ! Send to socket id [5] and data is '[status]' 
STATUS THREAD 0 
Info: (-3.35 dB) 
Method WRITE! Send to socket id [5] and data is '[outlevel 0:50 
]' 
El conector está marcado como no bloqueante y la operación solicitada lo bloquearía. 
Method WRITE! Error send() is 0 
Level modify of Vol 50% 
Info: (-24.13 dB) 
Level modify of Vol 50% 
Info: (-52.60 dB) 
Method WRITE! Send to socket id [5] and data is '[outlevel 0:50 
]' 
El conector está marcado como no bloqueante y la operación solicitada lo bloquearía. 
Method WRITE! Error send() is 0 
Level modify of Vol 50% 
Method READ! Send to socket id [5] and data is '[status]' 
hi0! 
send(): No route to host 
Method READ! Error send() is -1 
STATUS THREAD -1 
Method READ! Send to socket id [5] and data is '[status]' 
# 

但插槽号码不正确,应该是3或4,下一个代码:

在main()

... 
for(t=0;t<NUM_THREADS;t++) 
    { 

    printf("What's IP [%s] to connected now? %d\n",regIPConnected[t].ip,regIPConnected[t].idSocket); 

idSocket = regIPConnected [t] .idSocket;

rc = pthread_create(&(thread[t]), &attr,conectaThread,&idSocket); 
    if (rc) 
    { 
     printf("ERROR; return code from pthread_create() is %d\n", rc); 
    } 
    }//END FOR 

    printf("Out for\n\n!"); 

    /* Free attribute and wait for the other threads */ 
    pthread_attr_destroy(&attr); 

    for(t=0; t<NUM_THREADS; t++) 
    { 
    rc = pthread_join(thread[t], &status); 
    if (rc<0) { 
     printf("ERROR; return code from pthread_join() is %d\n", rc); 
    } 
    printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status); 
    }//END FOR 

    printf("Main: program completed. Exiting.\n"); 
    pthread_exit(NULL); 

}

的其他代码是相同的。为什么不把第一个插座“3”拿到插座5?以及为什么要完成线程?

感谢

+12

太长,没有阅读... – Alnitak 2012-04-27 10:27:19

+1

*我不知道,我该怎么做创建套接字并连接我在配置IP的文件中声明的differents ip * - 是否有可能把这句话改写成英文? – 2012-04-27 10:32:44

+0

对不起,我不是很好表达 – damlopez 2012-04-27 10:44:11

回答

1

尝试注释掉该行

printf("OK/NOK socket %d",socketClient); 

,看看你更成功。

有关详细信息,请参阅我对OP的评论。

+0

谢谢,我看到它,我认为这个问题可能是不正确的参数通过 – damlopez 2012-04-27 12:47:13

+0

这是溶剂,谢谢你! – damlopez 2012-05-14 15:47:12

+0

@ user1248467欢迎您。顺便说一句:我不介意,如果你会upvote,并接受我的答案,但...... ;-) – alk 2012-05-14 15:50:49

0

我没有看到你在套接字初始化函数中的任何地方声明了socketClient。如果它是一个全局的,它应该由一个互斥或其他一些序列化访问它的机制来保护。

一般来说,

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 

不应在正常情况下会失败。要么你超出了你的系统fd /套接字配额,或者更可能的是,缺乏对套接字的正确访问同步。

此外,如上所述,代码太多,上下文太少。