BIO socket -- Client (BIO_s_connect)

BIO_s_connect can be used as an client socket object, and has its private data struct BIO_CONNECT, which is stored in BIO.ptr.

In the struct, a status value int BIO_CONNECT.state is introduced to record the current state of socket, and indicate what to do next step. All the states are:

    #define BIO_CONN_S_BEFORE          1

    #define BIO_CONN_S_GET_IP          2

    #define BIO_CONN_S_GET_PORT     3

    #define BIO_CONN_S_CREATE_SOCKET   4

    #define BIO_CONN_S_CONNECT         5

    #define BIO_CONN_S_OK               6

    #define BIO_CONN_S_BLOCKED_CONNECT 7

    #define BIO_CONN_S_NBIO         8

An internal function conn_state() is used to perform the appropriate operation In a dead loop till reach the status 6(BIO_CONN_S_OK).

 

By the way, there is one thing to be noted, the C language don't have the feature to show if a member function is a internal or public; while in the C++ language, you may use public to indicate that the function is used for class object and protect to indicate for the derived class.

 

Use steps:

 1, create a socket bio and input host IP and port.

       You may use just one line:

cbio = BIO_new_connect("localhost:2000");

the host IP and port is in one string separated by ‘:’.

       Or you may initial the client BIO step by step:

    unsigned long ladd = inet_addr("127.0.0.1");

    cbio = BIO_new(BIO_s_connect());

    iRet = BIO_set_conn_ip(cbio, &ladd);

    iRet = BIO_set_conn_port(cbio, "2000");

 

2, then do connection:

    if(BIO_do_connect(cbio) <= 0) 

       // do something..

 

About the BIO_do_connect (), here is the definition:

#define BIO_do_connect(b)       BIO_do_handshake(b)

#define BIO_do_accept(b)  BIO_do_handshake(b)

#define BIO_do_handshake(b)   BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)

In BIO_C_DO_STATE_MACHINE conn_state()is called, in which a dead loop is used to update state, until BIO_CONN_S_OK is reached or error happens.

 

3, send and receive data

Then you may use the two function to send data,

int BIO_puts(BIO *b, const char *in);  // for string

int BIO_write(BIO *b, const void *in, int inl); // for raw data

and int BIO_read(BIO *b, void *out, int outl) to receive data.

If the remote peer closed, the BIO_read() will wake and return 0, return -1 if error happens;

 

Here is a complete client peer sample:

#include "stdafx.h"

#include

#include

#include

 

int _tmain(int argc, _TCHAR* argv[])

{

    BIO *cbio, *out;

    int len;

    char tmpbufin[1024] = {0};

    char tmpbufout[1024] = {0};

    ERR_load_crypto_strings();

 

    cbio = BIO_new_connect("localhost:2000");

 

    // another way to initial client BIO

    //unsigned long ladd = inet_addr("127.0.0.1");

    //cbio = BIO_new(BIO_s_connect());

    //if (NULL == cbio)  return 0;

    //iRet = BIO_set_conn_ip(cbio, &ladd);

    //iRet = BIO_set_conn_port(cbio, "2000");

   

    out = BIO_new_fp(stdout, BIO_NOCLOSE);

 

    if(BIO_do_connect(cbio) <= 0) {

       ERR_print_errors_fp(stderr);

       return 0;

       /* whatever ... */

    }

    printf("have connected to server/ninput data and press enter to send/n");

 

    for(;;) {

 

       memset(tmpbufout,0,sizeof(tmpbufout));

       memset(tmpbufin,0,sizeof(tmpbufin));

 

       scanf("%s", tmpbufout);

       if (0 == strcmp(tmpbufout, "quit")) break;

       if ((len = strlen(tmpbufout)) <= 0) break;

       len = BIO_write(cbio, tmpbufout, len + 1);

       if (len <= 0) break;

 

       len = BIO_read(cbio, tmpbufin, 1024);

       if(len <= 0) break;

       sprintf(tmpbufout, "from Server:%s/n", tmpbufin);

       BIO_write(out, tmpbufout, strlen(tmpbufout));

    }

    BIO_free(cbio);

    BIO_free(out);

}

你可能感兴趣的:(Open,SSL)