SCTP не будет устанавливать соединение после отключения - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь отправить непрерывные данные с клиентского компьютера на сервер, а затем отбросить соединение и восстановить его, чтобы продемонстрировать, как sctp может восстановить соединение.

Однако, когда соединение разорвано он не переподключается.

Вот код клиента:

int main() {
printf("SCTP Client started\n");
char localhost[32] = "127.0.0.1";

//Init client socket to a socket (see man SCTP) 
int client_sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);

//Create sctp_initmsg struct (struct from header)
//Allow two streams on the socket
struct sctp_initmsg sctp_initmsg;
sctp_initmsg.sinit_num_ostreams = 2;
sctp_initmsg.sinit_max_instreams = 2;
sctp_initmsg.sinit_max_attempts = 2;

//Sets socket options (socket_desc, level, optname, optval, len)
setsockopt(client_sd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg, sizeof(sctp_initmsg));


//Try to use specific addresses, if not use others in the association
//Setup server_address struct & bind to network interface
struct sockaddr_in server_address;
server_address.sin_family = PF_INET;
inet_pton(PF_INET, localhost, &server_address.sin_addr);
server_address.sin_port = htons(29008); 

//Connect using client socket and server_address
connect(client_sd, (struct sockaddr *)&server_address, sizeof(server_address));

struct sctp_event_subscribe events;
events.sctp_data_io_event = 1;
setsockopt(client_sd, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events));

//Declare a buffer for data received
char buffer[1024];

//Create a struct for sctp information
struct sctp_sndrcvinfo sndrcvinfo;


//Receive messages
//for(int i = 0; i < 8; i++) {
while(1) {

    //Clear the buffer (stops random buffer errors)
    bzero((void *)&buffer, sizeof(buffer));

    //Receive each message on the client socket into the buffer
    sctp_recvmsg(client_sd, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, NULL);
    printf("Stream %d received: %s\n", sndrcvinfo.sinfo_stream, buffer);
    printf(buffer);
    if(buffer == 'Data 5')
        {
        break;
        }
    //Print the stream number and data


}

//Close the client socket
close(client_sd);

return 0;

}

Вот код сервера

int main() {
printf("SCTP Server started\n");

//Init server socket to a socket (see man SCTP) 
int server_sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);

//Setup server_address struct & bind to network interface
struct sockaddr_in server_address;
server_address.sin_family = PF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY); //or use = inet_addr("ip");
server_address.sin_port = htons(29008); 
bind(server_sd, (struct sockaddr *)&server_address, sizeof(server_address) );

//Allow two streams on the socket
//Create sctp_initmsg struct (struct from header)
struct sctp_initmsg sctp_initmsg;
sctp_initmsg.sinit_num_ostreams = 2;
sctp_initmsg.sinit_max_instreams = 2;
sctp_initmsg.sinit_max_attempts = 2;

//Try to use specific addresses, if not use others in the association
//Sets socket options (socket_desc, level, optname, optval, len)
setsockopt(server_sd, IPPROTO_SCTP, SCTP_INITMSG, &sctp_initmsg, sizeof(sctp_initmsg));

//Listen to connections on the socket. backlog 5 is typical home workstation limit (?)  
listen(server_sd, 5);

//Create client address struct
struct sockaddr_in client_address;
int length = sizeof(client_address);
int client_sd;
char buff[INET_ADDRSTRLEN];
char message[32] = "Data  ";

//Run the server
while(1) {
    while(1) {
        //LOOP:
        //Initialise client socket to accept connections in request queue for servsocket
        client_sd = accept(server_sd, (struct sockaddr *)&client_address, &length);

        //Print connection with inet_ntop (converts network address to character string)
        printf("Connected to IP %s\n", inet_ntop(PF_INET, &client_address.sin_addr, buff, sizeof(buff)));   

        //Sent messages on two streams to the client
        while(1) {
            //sleep(2);
            for(int stream_num = 0; stream_num < 2; stream_num++) 
            {
                message[5] = stream_num +'1';
                char choice;
                    choice = getchar();
                    if(choice=='Q') 
                    {
                    message[5] = '5';
                    }

                //sctp_sendmsg(sctp_desc, msg, len(msg), to, tolen, ppid, stream_number, ttl, ctx, flags)
                sctp_sendmsg(client_sd, (void *)message, (size_t)strlen(message), NULL, 0, 0, 0, stream_num, 0, 0); 

                //Print what was sent on which stream
                printf("Sent %s to client on stream %d\n", message, stream_num);

            }
        }
        //goto LOOP;
        sleep(5);
        //Close the client socket
        close(client_sd);

    } //end while
} //end while
return 0;

}

Кто-нибудь есть идеи, где я иду не так? В настоящее время я пытаюсь выполнить это на 2 виртуальных машинах для отправки данных друг другу.

...