@@ -788,6 +788,38 @@ signed_size_type recv(socket_type s, buf* bufs, size_t count,
788
788
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
789
789
}
790
790
791
+ signed_size_type recv1 (socket_type s, void * data, size_t size,
792
+ int flags, boost::system::error_code& ec)
793
+ {
794
+ clear_last_error ();
795
+ #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
796
+ // Receive some data.
797
+ WSABUF buf;
798
+ buf.buf = const_cast <char *>(static_cast <const char *>(data));
799
+ buf.len = static_cast <ULONG>(size);
800
+ DWORD bytes_transferred = 0 ;
801
+ DWORD recv_flags = flags;
802
+ int result = error_wrapper (::WSARecv (s, &buf, 1 ,
803
+ &bytes_transferred, &recv_flags, 0 , 0 ), ec);
804
+ if (ec.value () == ERROR_NETNAME_DELETED)
805
+ ec = boost::asio::error::connection_reset;
806
+ else if (ec.value () == ERROR_PORT_UNREACHABLE)
807
+ ec = boost::asio::error::connection_refused;
808
+ else if (ec.value () == WSAEMSGSIZE || ec.value () == ERROR_MORE_DATA)
809
+ result = 0 ;
810
+ if (result != 0 )
811
+ return socket_error_retval;
812
+ ec = boost::system::error_code ();
813
+ return bytes_transferred;
814
+ #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
815
+ signed_size_type result = error_wrapper (::recv (s,
816
+ static_cast <char *>(data), size, flags), ec);
817
+ if (result >= 0 )
818
+ ec = boost::system::error_code ();
819
+ return result;
820
+ #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
821
+ }
822
+
791
823
size_t sync_recv (socket_type s, state_type state, buf* bufs,
792
824
size_t count, int flags, bool all_empty, boost::system::error_code& ec)
793
825
{
@@ -833,6 +865,51 @@ size_t sync_recv(socket_type s, state_type state, buf* bufs,
833
865
}
834
866
}
835
867
868
+ size_t sync_recv1 (socket_type s, state_type state, void * data,
869
+ size_t size, int flags, boost::system::error_code& ec)
870
+ {
871
+ if (s == invalid_socket)
872
+ {
873
+ ec = boost::asio::error::bad_descriptor;
874
+ return 0 ;
875
+ }
876
+
877
+ // A request to read 0 bytes on a stream is a no-op.
878
+ if (size == 0 && (state & stream_oriented))
879
+ {
880
+ ec = boost::system::error_code ();
881
+ return 0 ;
882
+ }
883
+
884
+ // Read some data.
885
+ for (;;)
886
+ {
887
+ // Try to complete the operation without blocking.
888
+ signed_size_type bytes = socket_ops::recv1 (s, data, size, flags, ec);
889
+
890
+ // Check if operation succeeded.
891
+ if (bytes > 0 )
892
+ return bytes;
893
+
894
+ // Check for EOF.
895
+ if ((state & stream_oriented) && bytes == 0 )
896
+ {
897
+ ec = boost::asio::error::eof;
898
+ return 0 ;
899
+ }
900
+
901
+ // Operation failed.
902
+ if ((state & user_set_non_blocking)
903
+ || (ec != boost::asio::error::would_block
904
+ && ec != boost::asio::error::try_again))
905
+ return 0 ;
906
+
907
+ // Wait for socket to become ready.
908
+ if (socket_ops::poll_read (s, 0 , -1 , ec) < 0 )
909
+ return 0 ;
910
+ }
911
+ }
912
+
836
913
#if defined(BOOST_ASIO_HAS_IOCP)
837
914
838
915
void complete_iocp_recv (state_type state,
@@ -905,6 +982,44 @@ bool non_blocking_recv(socket_type s,
905
982
}
906
983
}
907
984
985
+ bool non_blocking_recv1 (socket_type s,
986
+ void * data, size_t size, int flags, bool is_stream,
987
+ boost::system::error_code& ec, size_t & bytes_transferred)
988
+ {
989
+ for (;;)
990
+ {
991
+ // Read some data.
992
+ signed_size_type bytes = socket_ops::recv1 (s, data, size, flags, ec);
993
+
994
+ // Check for end of stream.
995
+ if (is_stream && bytes == 0 )
996
+ {
997
+ ec = boost::asio::error::eof;
998
+ return true ;
999
+ }
1000
+
1001
+ // Retry operation if interrupted by signal.
1002
+ if (ec == boost::asio::error::interrupted)
1003
+ continue ;
1004
+
1005
+ // Check if we need to run the operation again.
1006
+ if (ec == boost::asio::error::would_block
1007
+ || ec == boost::asio::error::try_again)
1008
+ return false ;
1009
+
1010
+ // Operation is complete.
1011
+ if (bytes >= 0 )
1012
+ {
1013
+ ec = boost::system::error_code ();
1014
+ bytes_transferred = bytes;
1015
+ }
1016
+ else
1017
+ bytes_transferred = 0 ;
1018
+
1019
+ return true ;
1020
+ }
1021
+ }
1022
+
908
1023
#endif // defined(BOOST_ASIO_HAS_IOCP)
909
1024
910
1025
signed_size_type recvfrom (socket_type s, buf* bufs, size_t count,
@@ -1188,6 +1303,39 @@ signed_size_type send(socket_type s, const buf* bufs, size_t count,
1188
1303
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
1189
1304
}
1190
1305
1306
+ signed_size_type send1 (socket_type s, const void * data, size_t size,
1307
+ int flags, boost::system::error_code& ec)
1308
+ {
1309
+ clear_last_error ();
1310
+ #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
1311
+ // Send the data.
1312
+ WSABUF buf;
1313
+ buf.buf = const_cast <char *>(static_cast <const char *>(data));
1314
+ buf.len = static_cast <ULONG>(size);
1315
+ DWORD bytes_transferred = 0 ;
1316
+ DWORD send_flags = flags;
1317
+ int result = error_wrapper (::WSASend (s, &buf, 1 ,
1318
+ &bytes_transferred, send_flags, 0 , 0 ), ec);
1319
+ if (ec.value () == ERROR_NETNAME_DELETED)
1320
+ ec = boost::asio::error::connection_reset;
1321
+ else if (ec.value () == ERROR_PORT_UNREACHABLE)
1322
+ ec = boost::asio::error::connection_refused;
1323
+ if (result != 0 )
1324
+ return socket_error_retval;
1325
+ ec = boost::system::error_code ();
1326
+ return bytes_transferred;
1327
+ #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
1328
+ #if defined(__linux__)
1329
+ flags |= MSG_NOSIGNAL;
1330
+ #endif // defined(__linux__)
1331
+ signed_size_type result = error_wrapper (::send (s,
1332
+ static_cast <const char *>(data), size, flags), ec);
1333
+ if (result >= 0 )
1334
+ ec = boost::system::error_code ();
1335
+ return result;
1336
+ #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
1337
+ }
1338
+
1191
1339
size_t sync_send (socket_type s, state_type state, const buf* bufs,
1192
1340
size_t count, int flags, bool all_empty, boost::system::error_code& ec)
1193
1341
{
@@ -1226,6 +1374,44 @@ size_t sync_send(socket_type s, state_type state, const buf* bufs,
1226
1374
}
1227
1375
}
1228
1376
1377
+ size_t sync_send1 (socket_type s, state_type state, const void * data,
1378
+ size_t size, int flags, boost::system::error_code& ec)
1379
+ {
1380
+ if (s == invalid_socket)
1381
+ {
1382
+ ec = boost::asio::error::bad_descriptor;
1383
+ return 0 ;
1384
+ }
1385
+
1386
+ // A request to write 0 bytes to a stream is a no-op.
1387
+ if (size == 0 && (state & stream_oriented))
1388
+ {
1389
+ ec = boost::system::error_code ();
1390
+ return 0 ;
1391
+ }
1392
+
1393
+ // Read some data.
1394
+ for (;;)
1395
+ {
1396
+ // Try to complete the operation without blocking.
1397
+ signed_size_type bytes = socket_ops::send1 (s, data, size, flags, ec);
1398
+
1399
+ // Check if operation succeeded.
1400
+ if (bytes >= 0 )
1401
+ return bytes;
1402
+
1403
+ // Operation failed.
1404
+ if ((state & user_set_non_blocking)
1405
+ || (ec != boost::asio::error::would_block
1406
+ && ec != boost::asio::error::try_again))
1407
+ return 0 ;
1408
+
1409
+ // Wait for socket to become ready.
1410
+ if (socket_ops::poll_write (s, 0 , -1 , ec) < 0 )
1411
+ return 0 ;
1412
+ }
1413
+ }
1414
+
1229
1415
#if defined(BOOST_ASIO_HAS_IOCP)
1230
1416
1231
1417
void complete_iocp_send (
@@ -1279,6 +1465,37 @@ bool non_blocking_send(socket_type s,
1279
1465
}
1280
1466
}
1281
1467
1468
+ bool non_blocking_send1 (socket_type s,
1469
+ const void * data, size_t size, int flags,
1470
+ boost::system::error_code& ec, size_t & bytes_transferred)
1471
+ {
1472
+ for (;;)
1473
+ {
1474
+ // Write some data.
1475
+ signed_size_type bytes = socket_ops::send1 (s, data, size, flags, ec);
1476
+
1477
+ // Retry operation if interrupted by signal.
1478
+ if (ec == boost::asio::error::interrupted)
1479
+ continue ;
1480
+
1481
+ // Check if we need to run the operation again.
1482
+ if (ec == boost::asio::error::would_block
1483
+ || ec == boost::asio::error::try_again)
1484
+ return false ;
1485
+
1486
+ // Operation is complete.
1487
+ if (bytes >= 0 )
1488
+ {
1489
+ ec = boost::system::error_code ();
1490
+ bytes_transferred = bytes;
1491
+ }
1492
+ else
1493
+ bytes_transferred = 0 ;
1494
+
1495
+ return true ;
1496
+ }
1497
+ }
1498
+
1282
1499
#endif // defined(BOOST_ASIO_HAS_IOCP)
1283
1500
1284
1501
signed_size_type sendto (socket_type s, const buf* bufs, size_t count,
0 commit comments