我正在启动UDP服务器,然后接受DTLS连接以读取传入数据。代码工作正常。但是,一旦我通过重新启动客户端套接字从客户端重用连接,服务器就无法读取任何内容。使用Cyassl库创建SSL实例。
在客户中: 套接字绑定和DTLS初始化很好,因为它重新使用之前使用的DTLS上下文。
在服务器中: 插座关闭和启动一切都很好,但我仍然无法接收到已接受的FD。
但是,如果我在关闭和启动UDP服务器之间完成5秒的睡眠,一切都很好。但我不想像睡眠一样使用阻塞I / O.
请帮忙。 服务器:
接受m_udp_fd中收到的数据:
if(FD_ISSET(m_udp_fd, &rfds))
{
if(m_accepted_flag==0)
{
udp_read_connect(m_udp_fd);
open_dtls_server();
if(m_ssl_accept(m_udp_fd)>0)
{
media_accepted_flag = 1;
}
}
else
{
// Read data
if(process_dtls_packet(m_udp_fd)<=0)
{
//Clear FD here
}
}
}
断开连接的位置取决于TCP连接是否断开。 这完全受到了打击:
if (FD_ISSET(m_fd, &rfds))
{
if(process_msg(m_fd)<=0)
{
closesocket(m_fd);
FD_CLR(m_fd,recv_fds);
if(recv_fdmax == m_fd)
{
recv_fdmax = max(x_fd,y_fd);
recv_fdmax = max(recv_fdmax,z_fd);
recv_fdmax = max(recv_fdmax,p_fd);
recv_fdmax = max(recv_fdmax,q_fd);
}
}
if(m_accepted_flag!=0)
{
m_accepted_flag = 0;
x_accepted_flag = 0;
//This sleep when kept works perfectly
Sleep(5000);
close_m_and_x_connection(&recv_fdmax,recv_fds,&m_udp_fd,&x_udp_fd);
}
}
UDP读取连接功能:
int udp_read_connect(SOCKET sockfd)
{
struct sockaddr cliaddr;
char b[1500];
int n;
int len = sizeof(cliaddr);
n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
(struct sockaddr*)&cliaddr, &len);
if (n > 0)
{
if (connect(sockfd, (const struct sockaddr*)&cliaddr,sizeof(cliaddr)) != 0)
printf("udp connect failed");
}
else
printf("recvfrom failed");
return sockfd;
}
打开DTLS服务器方法:这里dtls_ctx和dtls_meth是全局变量。
int open_dtls_server()
{
int verify_flag = OFF;
int error;
if(dtls_ctx!= NULL)
return;
dtls_ctx = ssl_create_context(DTLS_V1, &dtls_meth);
dtls_meth = CyaDTLSv1_server_method();
if(dtls_meth==NULL)
{
return -1;
}
dtls_ctx = CyaSSL_CTX_new(dtls_meth);
if(NULL == dtls_ctx)
{
ERR_print_errors_fp(stderr);
return -1;
}
if((status = LoadSSLCertificate(dtls_ctx,sslInfo,&error,0)) == 1)
{
return 0;
}
else
return 1;
if(CyaSSL_CTX_use_PrivateKey_file(dtls_ctx, SSL_SERVER_RSA_KEY, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
return -1;
}
if(CyaSSL_CTX_check_private_key(dtls_ctx) != 1)
{
return -1;
}
if(verify_flag)
{
if(!CyaSSL_CTX_load_verify_locations(dtls_ctx, SSL_SERVER_RSA_CA_CERT, NULL))
{
ERR_print_errors_fp(stderr);
return -1;
}
CyaSSL_CTX_set_verify(dtls_ctx, SSL_VERIFY_PEER, NULL);
}
CyaSSL_CTX_set_options(dtls_ctx, SSL_OP_ALL);
return 1;
}
m_ssl_accept功能:ssl_m也是一个全局变量。
int m_ssl_accept(int confd)
{
int ret;
if(ssl_m==NULL)
{
ssl_m = CyaSSL_new(dtls_ctx);
if (ssl_m == NULL)
printf("SSL_new failed");
CyaSSL_set_fd(ssl_m, confd);
}
do
{
if((ret = CyaSSL_accept(ssl_m))!= 1)
{
printf("Handshake Error on M Channel %d with FD: [%d]\n",
return -1;
}
}while(ret != 1);
return 1;
}