OPENSSL с C ++ и Posix - PullRequest
       11

OPENSSL с C ++ и Posix

1 голос
/ 14 марта 2011

У меня быстрый вопрос. Я настроил этот клиент в качестве своего рода примера, поэтому я не делаю с ним лишней работы; Я хотел, чтобы основная идея работала первой. Пока у меня это работает, с одним исключением:

Если я запускаю его, я вижу, что данные пересылаются с другой стороны (я использую python + twisted). Я могу писать без проблем, проблема возникает, когда я читаю. На стороне сервера я вижу, что текст приходит и снова отправляется обратно. Но на стороне клиента все задерживается. Я должен отправить три команды, чтобы увидеть, что что-то выходит.

например:

Я отправляю hello <newline> cruel <newline> world<newline> и получаю эхо-ответ hello, только после того, как я нажму, введите world.

Может кто-нибудь указать, почему или дать мне несколько советов?

Вот код.

#include <openssl/ssl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <cstdio>

//used for printing an error and then exiting.
inline void error(const char* message)
{
  fprintf(stderr, "%s\n", message);
  exit(EXIT_FAILURE);
}
//the buffer size we will be working with:
#define MAX_BUFF 4096

int main()
{
  int ret; //used for holding bytes read.
  int flag = 1; //our IOCTL flag.
  char buff[MAX_BUFF]; //a buffer for holding i/o data.
  fd_set rdesc, wdesc, srset, swset; //file descriptor sets.
  timeval tv; //used for holding the time select should wait.
  SSL_CTX* context = NULL; //ssl context.
  SSL* ssl = NULL; //main ssl object.
  sockaddr_in addr; //server socket address.
  int sock = 0;
//clean out the struct:
  bzero(&addr, sizeof(sockaddr_in));
//then fill it in.
  addr.sin_family = AF_INET;
  addr.sin_port = htons(4000);
  inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
//create the socket
  sock=socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    {
      error("Error creating initial socket.");
    }
//initialize SSL.
  SSL_load_error_strings();
  SSL_library_init();
//create the ssl context
  context = SSL_CTX_new(TLSv1_client_method());
  if (!context)
    {
      error("Could not create SSL context.");
    }
//connect the socket to the server.
  if (connect(sock, (sockaddr*)&addr, sizeof(sockaddr_in)) < 0)
    {
      error("Could not connect to specified socket.");
    }
//create the ssl object.
  ssl = SSL_new(context);
  if (!ssl)
    {
      error("Could not create ssl object.");
    }
//try to set the socket as the fd for the ssl object.
  if (!SSL_set_fd(ssl, sock))
    {
      error("Error, could not bind fd to the ssl object.");
    }
//link ssl up with the socket.
  if (!SSL_connect(ssl))
    {
      error("Could not perform ssl handshake.");
    }
ioctl(sock, FIONBIO, &flag);
//set our file descriptor sets.
  FD_SET(fileno(stdin), &wdesc);
  FD_SET(sock, &rdesc);
//wait for data, read, then print.
  while (1)
    {
//we need to zero out our i/o buffer.
      bzero(buff, MAX_BUFF);
//initialize our temp fd sets.
      srset = rdesc;
      swset = wdesc;
//each time select finishes it changes this to how much time it actually slept, so we     need to reset it.
      tv.tv_usec = 50*1000; //50 ms
      tv.tv_sec = 0;
//perform the actual select operation.
      select(sock+1, &srset, &swset, NULL, &tv);
//check to see if data was written on stdin (user input)
      if (FD_ISSET(fileno(stdin), &swset))
        {
//read inputted data.
          ret = read(fileno(stdin), buff, MAX_BUFF);
          if (ret)
            {
//write it to the socket.
              SSL_write(ssl, buff, ret);
            }
        }
//check to see if we received anything.
      if (FD_ISSET(sock, &srset))
        {
          printf("in if.\n");
//read it
          ret = SSL_read(ssl, buff, MAX_BUFF);
          printf("%d\n", ret);
          if (ret)
            {
//write it to screen.
              printf("%s\n", buff);
            }
        }
    }
  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...