pthread_create не удалось и вернул -1 (или 4294967295) - PullRequest
0 голосов
/ 29 июля 2010

Я пытаюсь воспроизвести пример из Сетевая безопасность с OpenSSL (Чандра и др. ). Программа состоит из client.c server.c common.h и common.c. client.c просто создает соединение с сервером через порт 6012, читает данные из stdin и затем отправляет эти данные на сервер. server.c читает данные из сокета и записывает их обратно в stdout.

Проблема заключается в том, что server.c всегда застревает в if(BIO_do_accept(acc) <= 0) в строке 62 и никогда не получает данные, отправленные с client.c, что прекрасно работает. Позже я обнаружил, что проблема в том, что pthread_create(...) в строке 66 (которая определена как THREAD_CREATE(...) в common.h) не удалось, и он вернул 4294967295. Поскольку THREAD_CREATE(...) не удалось, программа никогда не получит шанс запустить do_server_loop в server_thread(...), что объясняет, почему сервер так и не получил данные от клиента.

Как мне интерпретировать возвращаемые значения из pthread_create и как это исправить? PS. Позже я использовал strerror для преобразования 4294967295, и он вернул «Неизвестная ошибка».

Любая помощь будет высоко ценится!

/////////////////////////////////////////////// ///

Вот server.c:

#include "common.h" 
void do_server_loop(BIO *conn)
{
    int err, nread;
    char buf[80];

    do
    {
        fprintf(stderr, "server_loop executed.\n");
        for(nread = 0; nread < sizeof(buf); nread += err)
        {
            err = BIO_read(conn, buf + nread, sizeof(buf) - nread);
            if(err <= 0){
                break;
            }
        }
        fwrite(buf, 1, nread, stdout);
    }
    while (err > 0);
}

void THREAD_CC server_thread(void *arg)
{
    fprintf(stderr, "server_thread(void *arg) executed.\n");
    BIO *client = (BIO *)arg;
#ifndef WIN32
    pthread_detach(pthread_self());
#endif
    fprintf(stderr, "Connection opened.\n");
    do_server_loop(client);
    fprintf(stderr, "Connection closed.\n");

    BIO_free(client);
    ERR_remove_state(0);
#ifdef WIN32
    _endthread();
#else
    return 0;
#endif
}


int main(int argc, char *argv[])
{
    BIO     *acc, *client;
    int thread_create_result;
    THREAD_TYPE tid;

    init_OpenSSL();

    acc = BIO_new_accept(PORT);
    if(!acc){
        int_error("Error creating server socket");
    }

    if(BIO_do_accept(acc) <= 0){
        int_error("Error binding server socket");   
    }
    for(;;)
    {
        if(BIO_do_accept(acc) <= 0){
            int_error("Error accepting connection");
        }
        client = BIO_pop(acc);
        thread_create_result = THREAD_CREATE(tid, server_thread, client);
        if(thread_create_result != 0){
            fprintf(stderr, "THREAD_CREATE failed! returns: %s.\n", \
                                            strerror(thread_create_result));
            fprintf(stderr, "thread_create_result has the value: %u.\n", \
                                            thread_create_result);
            exit(-1);
        }
    }

    BIO_free(acc);
    return 0;
}

Вот common.h

#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>


#ifndef WIN32
#include <pthread.h>
#define THREAD_CC *
#define THREAD_TYPE         pthread_t
#define THREAD_CREATE(tid, entry, arg)  pthread_create(&(tid), NULL, \
                                   (entry), (arg))
#else
#include <windows.h>
#include <process.h>
#define THREAD_CC              __cdecl
#define THREAD_TYPE            DWORD
#define THREAD_CREATE(tid, entry, arg) do { _beginthread((entry), 0, (arg));\
                        (tid) = GetCurrentThreadId();\
                       } while (0)
#endif

#define PORT    "6012"      //port
#define SERVER  "10.1.251.24"   //server address
#define CLIENT  "10.1.21.46"    //client address

#define int_error(msg) handle_error(__FILE__, __LINE__, msg)
void handle_error(const char *file, int lineno, const char *msg);

void init_OpenSSL(void);

Makefile:

CC = gcc
OPENSSLDIR = /usr/local/ssl
#CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__  
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2

RPATH = -R${OPENSSLDIR}/lib
#LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread
LD = -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -pthread

OBJS = common.o

PROGS = server

all: ${PROGS}

server: server.o ${OBJS}
        ${CC} server.o ${OBJS} -o server ${LD}


clean:;
        ${RM} ${PROGS} *.ln *.BAK *.bak *.o

Ответы [ 2 ]

2 голосов
/ 29 июля 2010

Изменить

if(thread_create_result = !0){

на

if(thread_create_result != 0){

Кроме того, вы можете использовать функцию strerror для преобразования кода ошибки в понятный человекуформа.

0 голосов
/ 03 августа 2010

добавить -D_REENTRANT в командной строке компиляции и -lpthread в командной строке ссылки. -D_REENTRANT сообщит библиотекам C / C ++, что ваша программа находится в многопоточном режиме, а -lpthread просто загрузит общую библиотеку libpthread.so во время выполнения. Я нашел это в руководстве по потокам POSIX Уильяма Гаррисона и этой ссылке .

Вот Makefile:

CC = gcc
OPENSSLDIR = /usr/local/ssl
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__  

RPATH = -R${OPENSSLDIR}/lib
LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread

OBJS = common.o

PROGS = server

all: ${PROGS}

server: server.o ${OBJS}
        ${CC} server.o ${OBJS} -o server ${LD}


clean:;
        ${RM} ${PROGS} *.ln *.BAK *.bak *.o
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...