你如何使用带有线程的套接字? c ++与ubuntu

时间:2012-07-26 02:43:13

标签: c++ multithreading sockets

我想知道为什么在使用带套接字的线程时我无法发送数据。

我想知道为什么当我使用第一种方法(没有线程)发送时,它可以工作,但是使用第二种方法,它无法发送数据。

这是我的声明:

int main(int argc, char *argv[]) 
{
    int sd, rc, i;
    struct sockaddr_in cliAddr, remoteServAddr;
    struct hostent *h;
    h = gethostbyname(argv[1]);
    inet_ntoa(*(struct in_addr *)h->h_addr_list[0]));

    remoteServAddr.sin_family = h->h_addrtype;
    memcpy((char *) &remoteServAddr.sin_addr.s_addr,h->h_addr_list[0], h->h_length);
    remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT);

    /* socket creation */
    sd = socket(AF_INET,SOCK_DGRAM,0);

    /* bind any port */
    cliAddr.sin_family = AF_INET;
    cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    cliAddr.sin_port = htons(0);

    rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));

    socklen_t remoteServLen = sizeof(remoteServAddr);
    //this is my own class to store the pointers to the following variables
    clientInfo ci(&sd,&rc,&remoteServLen,&remoteServAddr,&cliAddr);

/ 第一种方法 /

    char *data;
    char input[MAX_MSG];

    std::cout << "Enter message to send (type /q to quit) : ";  
    std::cin >> input;
    data = input;

    rc = sendto(*(ci.getSd()), data, strlen(data)+1, 0,(struct sockaddr *) ci.getCliAddr(),*(ci.getCliLen()));

/ 第一种方法 /

/ 第二种方法 /

    pthread_t thread[2];
    int status;

    status = pthread_create (&thread[1], NULL, sendFunction,&ci);

/ 第二种方法 /

}

/ 这是我的线程方法 /

void* sendFunction (void* temp)
{

    int status;
    char *data;
    char input[MAX_MSG];
    int rc;

    clientInfo *ci;
    ci = (clientInfo*)temp;

    status = pthread_detach (pthread_self ());

    while(1)
    {
        std::cout << "Enter message to send (type /q to quit) : ";  
        std::cin >> input;
        data = input;


        rc = sendto(*(ci->getSd()), data, strlen(data)+1, 0,(struct sockaddr *) ci->getCliAddr(),*(ci->getCliLen()));

        if(rc<0) 
        {
            printf("Cannot send data %s \n",data);
        }
    }//end of while loop

    return NULL;
}//end of sendFunction method

:)提前谢谢! :d

1 个答案:

答案 0 :(得分:4)

如果您提供了目标平台/环境,那就太好了。我假设你正在使用Linux,所以我最好的猜测是你的线程在它有任何机会发送任何东西之前实际终止。你可能想知道为什么这样,因为你已经脱离了它。嗯,那些在POSIX线程上阅读过一些抽象文章/书籍的人是一个非常常见的错误。事实是 - 它并不像那样。这在pthread_detach()的Linux手册页中明确说明:

The detached attribute merely determines the behavior of the system when the
thread terminates; it does not prevent the thread from being terminated if the
process terminates using exit(3) (or equivalently, if the main thread
returns).

我建议您实际join()“从主线程发送”线程,看看是否有效。如果不是 - 请回来更新。此外,使用调试器永远不会受到伤害 - 它很可能会立即显示出错误。

另一方面,线程不是C10K problem的解决方案。例如,创建两个线程只是为了拥有两个(阻塞)发送者,根本不是这样做的。为此,操作系统提供异步通知机制。例如,Linux获得epoll,FreeBSD(和OS X :-))建立在kqueue之上。还有poll,select,port completion等。还有一些API包含这些机制(为了便携性和/或简化原因)。 libeventBoost.Asio是最受欢迎的选择。

希望它有所帮助。