具有阻塞服务器的非阻塞套接字客户端

时间:2021-05-22 19:26:44

标签: c++ linux sockets openssl

我需要向站点发送数据而不会在单次连接中收到延迟。我还没有找到比使用异步套接字更好的方法。我认为该站点使用了阻塞连接,而我无权访问服务器。 我在我的服务器上运行测试,它也使用阻塞连接。我在php上写了一个简单的程序。

<?php
$ms=round(microtime(true)*1000).' '.mt_rand(111,999);
sleep(1);
file_put_contents('ms.txt',$ms."\r\n",FILE_APPEND|LOCK_EX);
echo $ms;
?>

我使用非阻塞套接字在 C++ 上编写的客户端程序。 这是我的 C++ 非阻塞套接字客户端:

#include <unistd.h>
#include <fcntl.h>
#include <netdb.h> 
#include <arpa/inet.h>
#include <netinet/in.h> 
#include <netinet/tcp.h>
#include <sys/socket.h> 
#include <openssl/ssl.h>
 
using namespace std;

int main(int argc, char *argv[]){
 struct sockaddr_in sa;
 int s=socket(AF_INET,SOCK_STREAM,0);
 sa.sin_family=AF_INET;
 sa.sin_port=htons(443);
 sa.sin_addr.s_addr=inet_addr("100.1.1.1");//ip of my site 
 socklen_t socklen=sizeof(sa);
 int one = 1;
 setsockopt(s, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
 connect(s,(struct sockaddr *)&sa,sizeof(sa));
 int flags;
 if((flags = fcntl(s, F_GETFL, 0))==-1)flags=0;
 fcntl(s, F_SETFL, flags | O_NONBLOCK);
 SSL *ssl;
 SSL_CTX *ctx=SSL_CTX_new(SSLv23_client_method());
 ssl=SSL_new(ctx);
 SSL_set_fd(ssl,s);
 fd_set fds;
 FD_ZERO(&fds);
 FD_SET(s, &fds);
 while(1){
  int err=SSL_connect(ssl);
  if(err==1){break;}
  int decodedError = SSL_get_error(ssl,err);
  if(decodedError==SSL_ERROR_WANT_READ){
   int result=select(s+1,&fds,NULL,NULL,NULL);
   if(result==-1){
    printf("Read-select error.\n");
    return -1;
   }
  }else if(decodedError==SSL_ERROR_WANT_WRITE){
   int result=select(s+1,NULL,&fds,NULL,NULL);
   if(result==-1){
    printf("Write-select error.\n");
    return -1;
   }
  }else{
   printf("Error creating SSL connection. err=%x\n", decodedError);
   return -1;
  }
 }
 for(int i=0;i<20;i++){
  SSL_write(ssl,"GET /ms.php HTTP/1.1\r\nHost: site.co.uk\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n",95);
 }
 sleep(20);
 close(s);
 return 0;
}

客户完成工作,没有出现错误。 但是在服务器上的文件 ms.txt 中,每个请求都有 1 秒的延迟。

1621710871272 236
1621710872275 765
1621710873279 549
1621710874281 250
1621710875284 559
1621710876288 607
1621710877291 787
1621710878294 627
1621710879297 352
1621710880300 305
1621710881302 860
1621710882306 649
1621710883309 222
1621710884312 974
1621710885315 628
1621710886317 184
1621710887320 532
1621710888322 142
1621710889325 161
1621710890329 114

我做错了什么以及如何在一个连接中发送数据而不会出现延迟?

0 个答案:

没有答案