2015-11-03 43 views
0

當我運行服務器程序時,它會執行並且將監聽連接,當我執行客戶端程序時,客戶端和服務器都將退出程序。 我不知道爲什麼會發生我正在運行服務器sudo ./server 9000和我的客戶端sudo ./client nandan 9000。有人能幫助我解決這個問題,並提前致謝。服務器和客戶端退出程序

服務器程序

#include <stdio.h> 
#include <errno.h> 
#include <unistd.h> 
#include <malloc.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <resolv.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 
#include <openssl/x509.h> 
#include <openssl/x509v3.h> 
#define FAIL -1 
/*--- OpenListener - create server socket---*/ 

int OpenListener(int port) 
{ 
    int sd; 
    struct sockaddr_in addr; 

    sd = socket(AF_INET, SOCK_STREAM, 0); 
    bzero(&addr, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = INADDR_ANY; 
    if (bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0) 
    { 
    perror("can't bind port"); 
    abort(); 
    } 
    if (listen(sd, 10) != 0) 
    { 
    perror("Can't configure listening port"); 
    abort(); 
    } 
    return sd; 
    } 

/*--- InitServerCTX - initialize SSL server and create context  ---*/ 
SSL_CTX* InitServerCTX(void) 
{ 
    SSL_library_init(); 
    SSL_METHOD *method; 
    SSL_CTX *ctx; 

    OpenSSL_add_all_algorithms();  /* load & register all cryptos, etc. */ 
    SSL_load_error_strings();   /* load all error messages */ 
    method = SSLv23_server_method();  /* create new server-method instance */ 
    ctx = SSL_CTX_new(method);   /* create new context from method */ 
    if (ctx == NULL) 
    { 
    ERR_print_errors_fp(stderr); 
    abort(); 
    } 
    return ctx; 
} 

/*--- LoadCertificates - load from files---*/ 

void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile) 
{ 
/* set the local certificate from CertFile */ 
    if (SSL_CTX_use_certificate_file(ctx, "/etc/apache2/ssl/myfirst.pem", SSL_FILETYPE_PEM) <= 0) 
    { 
    ERR_print_errors_fp(stderr); 
    abort(); 
    } 
/* set the private key from KeyFile (may be the same as CertFile) */ 
    if (SSL_CTX_use_PrivateKey_file(ctx, "/etc/apache2/ssl/apache.pem", SSL_FILETYPE_PEM) <= 0) 
    { 
    ERR_print_errors_fp(stderr); 
    abort(); 
    } 
/* verify private key */ 
    if (!SSL_CTX_check_private_key(ctx)) 
    { 
    fprintf(stderr, "Private key does not match the public certificate\n"); 
    abort(); 
    } 
} 

/*--- ShowCerts - print out certificates.       ---*/ 

void ShowCerts(SSL* ssl) 
{ 
    X509 *cert; 
    char *line; 

    cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */ 
    if (cert != NULL) 
    { 
    printf("Server certificates:\n"); 
    line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); 
    printf("Subject: %s\n", line); 
    free(line); 
    line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); 
    printf("Issuer: %s\n", line); 
    free(line); 
    X509_free(cert); 
    } 
    else 
    printf("No certificates.\n"); 
} 
/*--- Servlet - SSL servlet (contexts can be shared) ---*/ 

void Servlet(SSL* ssl) /* Serve the connection -- threadable */ 
{ 
    char buf[1024]; 
    char reply[1024]; 
    int sd, bytes; 
    const char* HTMLecho="<html><body><pre>%s</pre></body></html>\n\n"; 

    if (SSL_accept(ssl) == FAIL)     /* do SSL-protocol accept */ 
    ERR_print_errors_fp(stderr); 
    else 
    { 
    ShowCerts(ssl);        /* get any certificates */ 
    bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */ 
     if (bytes > 0) 
     { 
     buf[bytes] = 0; 
     printf("Client msg: \"%s\"\n", buf); 
     sprintf(reply, HTMLecho, buf);   /* construct reply */ 
     SSL_write(ssl, reply, strlen(reply)); /* send reply */ 
     } 
     else 
     ERR_print_errors_fp(stderr); 
    } 
    sd = SSL_get_fd(ssl);       /* get socket connection */ 
    SSL_free(ssl);         /* release SSL state */ 
    close(sd);          /* close connection */ 
} 

/*--- main - create SSL socket server---*/ 

int main(int count, char *strings[]) 
{ 
    SSL_CTX *ctx; 
    int server , c; 
    char *portnum; 

    if (count != 2) 
    { 
    printf("Usage: %s <portnum>\n", strings[0]); 
    exit(0); 
    } 
    portnum = strings[1]; 
    printf("%s" , portnum); 
    ctx = InitServerCTX();        /* initialize SSL */ 
    LoadCertificates(ctx, "newreq.pem", "newreq.pem"); /* load certs */ 
    server = OpenListener(atoi(portnum));    /* create server socket */ 
    while (1) 
    { 
    struct sockaddr_in addr; 
    SSL *ssl; 
    int client = accept(server, (struct sockaddr *)&addr, (socklen_t*)&c); 
    printf("Connection: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); 
    ssl = SSL_new(ctx);    /* get new SSL state with context */ 
    SSL_set_fd(ssl, client); /* set connection socket to SSL state */ 
    Servlet(ssl);    /* service connection */ 
    } 
    close(server);     /* close server socket */ 
    SSL_CTX_free(ctx);  /* release context */ 
} 

我的客戶端程序

#include <stdio.h> 
#include <errno.h> 
#include <unistd.h> 
#include <malloc.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <resolv.h> 
#include <netdb.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 

#define FAIL -1 

/*--- OpenConnection - create socket and connect to server---*/ 

int OpenConnection(const char *hostname, int port) 
{ 
    int sd; 
    struct hostent *host; 
    struct sockaddr_in addr; 

    if ((host = gethostbyname(hostname)) == NULL) 
    { 
    perror(hostname); 
    abort(); 
    } 
    sd = socket(AF_INET, SOCK_STREAM, 0); 
    bzero(&addr, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(port); 
    addr.sin_addr.s_addr = *(long*)(host->h_addr); 
    if (connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0) 
    { 
    close(sd); 
    perror(hostname); 
    abort(); 
    } 
    return sd; 
} 

/*--- InitCTX - initialize the SSL engine---*/ 

SSL_CTX* InitCTX(void) 
{ 
    SSL_library_init(); 
    SSL_METHOD *method; 
    SSL_CTX *ctx; 

    OpenSSL_add_all_algorithms();  /* Load cryptos, et.al. */ 
    SSL_load_error_strings();   /* Bring in and register error messages */ 
    method = SSLv23_client_method();  /* Create new client-method instance */ 
    ctx = SSL_CTX_new(method);  /* Create new context */ 
    if (ctx == NULL) 
    { 
    ERR_print_errors_fp(stderr); 
    abort(); 
    } 
    return ctx; 
} 

/*--- ShowCerts - print out the certificates---*/ 

void ShowCerts(SSL* ssl) 
{  
    X509 *cert; 
    char *line; 

    cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */ 
    if (cert != NULL) 
    { 
    printf("Server certificates:\n"); 
    line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); 
    printf("Subject: %s\n", line); 
    free(line);    /* free the malloc'ed string */ 
    line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); 
    printf("Issuer: %s\n", line); 
    free(line);   /* free the malloc'ed string */ 
    X509_free(cert);  /* free the malloc'ed certificate copy */ 
    } 
    else 
    printf("No certificates.\n"); 
} 

/*--- main - create SSL context and connect---*/ 

int main(int count, char *strings[]) 
{ 

    SSL_CTX *ctx; 
    int server; 
    SSL *ssl; 
    char buf[1024]; 
    int bytes; 
    char *hostname, *portnum; 

    if (count != 3) 
    { 
    printf("usage: %s <hostname> <portnum>\n", strings[0]); 
    exit(0); 
    } 
hostname=strings[1]; 
portnum=strings[2]; 

    ctx = InitCTX(); 
    server = OpenConnection(hostname, atoi(portnum)); 
    ssl = SSL_new(ctx);  /* create new SSL connection state */ 
    SSL_set_fd(ssl, server);  /* attach the socket descriptor */ 
    if (SSL_connect(ssl) == FAIL) /* perform the connection */ 
    ERR_print_errors_fp(stderr); 
    else 
    { 
    char *msg = "Hello???"; 
    printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); 
    ShowCerts(ssl);    /* get any certs */ 
    SSL_write(ssl, msg, strlen(msg)); /* encrypt & send message */ 
    bytes = SSL_read(ssl, buf, sizeof(buf));/* get reply & decrypt */ 
    buf[bytes] = 0; 
    printf("Received: \"%s\"\n", buf); 
    SSL_free(ssl);   /* release connection state */ 
    } 
    close(server);  /* close socket */ 
    SSL_CTX_free(ctx);  /* release context */ 
} 

回答

0

你的服務器和客戶端程序嘗試bind()到同一端口9000。它會失敗的客戶端,它會abort()

不知道爲什麼服務器也存在。

客戶端連接到服務器的apis /邏輯不正確。您需要在客戶端創建套接字和connect()而不是bind() - listen() - accept()

+0

通常它們連接到相同的端口,並且客戶端中的apis/logic連接到服務器是不正確的。那是什麼意思? – nandan