@@ -593,19 +593,204 @@ test "ChildExit" {
593
593
}
594
594
}
595
595
596
- test "Socket" {
596
+ test "Socket/TCP " {
597
597
if (builtin .target .os .tag == .wasi ) {
598
598
return error .SkipZigTest ;
599
599
}
600
600
601
- var sock : std.posix.socket_t = undefined ;
601
+ var server : std.posix.socket_t = undefined ;
602
602
try single (.socket , .{
603
603
.domain = std .posix .AF .INET ,
604
604
.flags = std .posix .SOCK .STREAM | std .posix .SOCK .CLOEXEC ,
605
605
.protocol = std .posix .IPPROTO .TCP ,
606
- .out_socket = & sock ,
606
+ .out_socket = & server ,
607
607
});
608
- try single (.close_socket , .{ .socket = sock });
608
+
609
+ try std .posix .setsockopt (server , std .posix .SOL .SOCKET , std .posix .SO .REUSEADDR , & std .mem .toBytes (@as (c_int , 1 )));
610
+ if (@hasDecl (std .posix .SO , "REUSEPORT" )) {
611
+ try std .posix .setsockopt (server , std .posix .SOL .SOCKET , std .posix .SO .REUSEPORT , & std .mem .toBytes (@as (c_int , 1 )));
612
+ }
613
+
614
+ var client : std.posix.socket_t = undefined ;
615
+ try single (.socket , .{
616
+ .domain = std .posix .AF .INET ,
617
+ .flags = std .posix .SOCK .STREAM | std .posix .SOCK .CLOEXEC ,
618
+ .protocol = std .posix .IPPROTO .TCP ,
619
+ .out_socket = & client ,
620
+ });
621
+
622
+ const address = std .net .Address .initIp4 (.{ 127 , 0 , 0 , 1 }, 3131 );
623
+ try std .posix .bind (server , & address .any , address .getOsSockLen ());
624
+ try std .posix .listen (server , 1 );
625
+
626
+ var client_comm : std.posix.socket_t = undefined ;
627
+ var client_addr_posix : std .posix .sockaddr align (4 ) = undefined ;
628
+ var client_addr_len : posix.socklen_t = @sizeOf (std .posix .sockaddr );
629
+ try multi (.{
630
+ op (.accept , .{
631
+ .socket = server ,
632
+ .out_socket = & client_comm ,
633
+ .out_addr = & client_addr_posix ,
634
+ .inout_addrlen = & client_addr_len ,
635
+ }, .unlinked ),
636
+ op (.connect , .{
637
+ .socket = client ,
638
+ .addr = & address .any ,
639
+ .addrlen = address .getOsSockLen (),
640
+ }, .unlinked ),
641
+ });
642
+
643
+ const client_addr = std .net .Address .initPosix (& client_addr_posix );
644
+ try std .testing .expectEqual (address .in .sa .addr , client_addr .in .sa .addr );
645
+
646
+ var buf1 : [32 ]u8 = undefined ;
647
+ var wlen1 : usize = 0 ;
648
+ var rlen1 : usize = 0 ;
649
+ var buf2 : [32 ]u8 = undefined ;
650
+ var wlen2 : usize = 0 ;
651
+ var rlen2 : usize = 0 ;
652
+ try multi (.{
653
+ op (.send , .{ .socket = client_comm , .buffer = "PING" , .out_written = & wlen1 }, .soft ),
654
+ op (.recv , .{ .socket = client , .buffer = & buf1 , .out_read = & rlen1 }, .soft ),
655
+ op (.send , .{ .socket = client , .buffer = "PONG" , .out_written = & wlen2 }, .soft ),
656
+ op (.recv , .{ .socket = client_comm , .buffer = & buf2 , .out_read = & rlen2 }, .unlinked ),
657
+ });
658
+
659
+ try std .testing .expectEqual (wlen1 , 4 );
660
+ try std .testing .expectEqual (rlen1 , 4 );
661
+ try std .testing .expectEqual (wlen1 , wlen2 );
662
+ try std .testing .expectEqual (rlen1 , rlen2 );
663
+ try std .testing .expectEqualSlices (u8 , buf1 [0.. rlen1 ], "PING" );
664
+ try std .testing .expectEqualSlices (u8 , buf2 [0.. rlen2 ], "PONG" );
665
+
666
+ try single (.shutdown , .{ .socket = client , .how = .both });
667
+ try single (.close_socket , .{ .socket = client });
668
+ try single (.close_socket , .{ .socket = server });
669
+ }
670
+
671
+ test "Socket/UDP" {
672
+ if (builtin .target .os .tag == .wasi ) {
673
+ return error .SkipZigTest ;
674
+ }
675
+
676
+ var server : std.posix.socket_t = undefined ;
677
+ try single (.socket , .{
678
+ .domain = std .posix .AF .INET ,
679
+ .flags = std .posix .SOCK .DGRAM | std .posix .SOCK .CLOEXEC ,
680
+ .protocol = std .posix .IPPROTO .UDP ,
681
+ .out_socket = & server ,
682
+ });
683
+
684
+ try std .posix .setsockopt (server , std .posix .SOL .SOCKET , std .posix .SO .REUSEADDR , & std .mem .toBytes (@as (c_int , 1 )));
685
+ if (@hasDecl (std .posix .SO , "REUSEPORT" )) {
686
+ try std .posix .setsockopt (server , std .posix .SOL .SOCKET , std .posix .SO .REUSEPORT , & std .mem .toBytes (@as (c_int , 1 )));
687
+ }
688
+
689
+ var client : std.posix.socket_t = undefined ;
690
+ try single (.socket , .{
691
+ .domain = std .posix .AF .INET ,
692
+ .flags = std .posix .SOCK .DGRAM | std .posix .SOCK .CLOEXEC ,
693
+ .protocol = std .posix .IPPROTO .UDP ,
694
+ .out_socket = & client ,
695
+ });
696
+
697
+ try std .posix .setsockopt (client , std .posix .SOL .SOCKET , std .posix .SO .REUSEADDR , & std .mem .toBytes (@as (c_int , 1 )));
698
+ if (@hasDecl (std .posix .SO , "REUSEPORT" )) {
699
+ try std .posix .setsockopt (client , std .posix .SOL .SOCKET , std .posix .SO .REUSEPORT , & std .mem .toBytes (@as (c_int , 1 )));
700
+ }
701
+
702
+ const saddress = std .net .Address .initIp4 (.{ 127 , 0 , 0 , 1 }, 3131 );
703
+ const caddress = std .net .Address .initIp4 (.{ 127 , 0 , 0 , 1 }, 3232 );
704
+ try std .posix .bind (server , & saddress .any , saddress .getOsSockLen ());
705
+ try std .posix .bind (client , & caddress .any , caddress .getOsSockLen ());
706
+
707
+ var ping_msg : posix.msghdr_const = .{
708
+ .name = @ptrCast (& caddress .any ),
709
+ .namelen = caddress .getOsSockLen (),
710
+ .iov = &.{
711
+ .{
712
+ .base = "PING" ,
713
+ .len = "PING" .len ,
714
+ },
715
+ },
716
+ .iovlen = 1 ,
717
+ .control = null ,
718
+ .controllen = 0 ,
719
+ .flags = 0 ,
720
+ };
721
+
722
+ var pong_msg : posix.msghdr_const = .{
723
+ .name = @ptrCast (& saddress .any ),
724
+ .namelen = saddress .getOsSockLen (),
725
+ .iov = &.{
726
+ .{
727
+ .base = "PONG" ,
728
+ .len = "PONG" .len ,
729
+ },
730
+ },
731
+ .iovlen = 1 ,
732
+ .control = null ,
733
+ .controllen = 0 ,
734
+ .flags = 0 ,
735
+ };
736
+
737
+ var buf1 : [32 ]u8 = undefined ;
738
+ var recv_addr1 : std .posix .sockaddr align (4 ) = undefined ;
739
+ var recv_iovec1 : [1 ]posix.iovec = .{.{
740
+ .base = & buf1 ,
741
+ .len = buf1 .len ,
742
+ }};
743
+ var recv_msg1 : posix.msghdr = .{
744
+ .name = @ptrCast (& recv_addr1 ),
745
+ .namelen = @sizeOf (@TypeOf (recv_addr1 )),
746
+ .iov = & recv_iovec1 ,
747
+ .iovlen = 1 ,
748
+ .control = null ,
749
+ .controllen = 0 ,
750
+ .flags = 0 ,
751
+ };
752
+
753
+ var buf2 : [32 ]u8 = undefined ;
754
+ var recv_addr2 : std .posix .sockaddr align (4 ) = undefined ;
755
+ var recv_iovec2 : [1 ]posix.iovec = .{.{
756
+ .base = & buf2 ,
757
+ .len = buf2 .len ,
758
+ }};
759
+ var recv_msg2 : posix.msghdr = .{
760
+ .name = @ptrCast (& recv_addr2 ),
761
+ .namelen = @sizeOf (@TypeOf (recv_addr2 )),
762
+ .iov = & recv_iovec2 ,
763
+ .iovlen = 1 ,
764
+ .control = null ,
765
+ .controllen = 0 ,
766
+ .flags = 0 ,
767
+ };
768
+
769
+ var wlen1 : usize = 0 ;
770
+ var rlen1 : usize = 0 ;
771
+ var wlen2 : usize = 0 ;
772
+ var rlen2 : usize = 0 ;
773
+ try multi (.{
774
+ op (.send_msg , .{ .socket = server , .msg = & ping_msg , .out_written = & wlen1 }, .soft ),
775
+ op (.recv_msg , .{ .socket = client , .out_msg = & recv_msg1 , .out_read = & rlen1 }, .soft ),
776
+ op (.send_msg , .{ .socket = client , .msg = & pong_msg , .out_written = & wlen2 }, .soft ),
777
+ op (.recv_msg , .{ .socket = server , .out_msg = & recv_msg2 , .out_read = & rlen2 }, .unlinked ),
778
+ });
779
+
780
+ const addr1 = std .net .Address .initPosix (& recv_addr1 );
781
+ std .debug .assert (addr1 .eql (saddress ));
782
+ const addr2 = std .net .Address .initPosix (& recv_addr2 );
783
+ std .debug .assert (addr2 .eql (caddress ));
784
+
785
+ try std .testing .expectEqual (wlen1 , 4 );
786
+ try std .testing .expectEqual (rlen1 , 4 );
787
+ try std .testing .expectEqual (wlen1 , wlen2 );
788
+ try std .testing .expectEqual (rlen1 , rlen2 );
789
+ try std .testing .expectEqualSlices (u8 , buf1 [0.. rlen1 ], "PING" );
790
+ try std .testing .expectEqualSlices (u8 , buf2 [0.. rlen2 ], "PONG" );
791
+
792
+ try single (.close_socket , .{ .socket = client });
793
+ try single (.close_socket , .{ .socket = server });
609
794
}
610
795
611
796
test "EventSource" {
0 commit comments