非阻塞套接字接收

时间:2018-04-17 12:44:21

标签: c sockets

我有一个简单的服务器程序,看起来像下面的代码:

Private Sub ProdComp_Change()
    '~~> when working with Rows, Please do not use `Integer`. Use `Long`
    Dim RowMax As Long, countexit As Long, i As Long
    Dim ws As Worksheet
    Dim cellcombo2 As String
    Dim col As New Collection, itm As Variant

    Set ws = ThisWorkbook.Sheets("products")
    RowMax = ws.Cells(Rows.Count, "B").End(xlUp).Row

    For i = 2 To RowMax
        If ws.Cells(i, "B").Value = ProdComp.Text Then
            '~~> On error resume next will
            '~~> create a unique collection
            On Error Resume Next
            col.Add ws.Cells(i, "c").Value, CStr(ws.Cells(i, "c").Value)
            On Error GoTo 0
        End If
    Next i

    Me.LBType.Clear

    If col.Count > 0 Then
        For Each itm In col
            LBType.AddItem itm
        Next
    End If
End Sub

是否可以检查是否有任何数据来自客户端而没有阻塞,以便服务器可以不断地将数据转储到客户端?

2 个答案:

答案 0 :(得分:2)

是的,当然,有很多解决方案,AFAIK:

并非所有操作系统都可用。

答案 1 :(得分:1)

如果要定义非阻塞socket,则在打开套接字时应在socket类型参数中添加SOCK_NONBLOCK值。例如,此语句打开一个RAW套接字,其中可以以非阻塞模式读取和写入TCP数据包:

recv_socket = socket(AF_INET, SOCK_RAW | SOCK_NONBLOCK
                         , IPPROTO_TCP);

然后你可以调用read函数如下:

typedef struct
{
    struct iphdr ip;
    struct tcphdr tcp;
    char datagram[DATAGRAM_SIZE];
} TCP_PACKET;

int ret_read = 0;
TCP_PACKET recv_packet;

ret_read = read(recv_socket, reinterpret_cast<void*>(&received_packet)
, sizeof(received_packet));

if(ret_read >= 0)
{
    // read occured in success
}

注意:永远不要在read中使用const-size:

ret_read = read(recv_socket, reinterpret_cast<void*>(&received_packet)
, 65536);    // makes segmentation fault

在读取数据包时会导致分段错误。只需使用sizeof