当前位置: 首页 > 知识库问答 >
问题:

从套接字上重新读取数据

寇升
2023-03-14

我正在创建一个简单的服务器/客户端UDP套接字程序,我遇到了一个问题。

问题是recvfrom()函数一直在重新读取上次发送的数据。

因此,如果我从客户端向服务器发送两个数据包,那么recvfrom()将读取第一个数据包并打印其数据,然后它将不断地反复读取第二个数据包。

据我所知,一旦成功执行读取操作,数据包应该从套接字中删除,但这似乎没有发生。

我知道客户端没有重新发送数据,因为每当客户端发送数据时都会写入控制台输出。

这是发送程序的函数

int sendPacket(int socketFd, int type, char *typeString, char *data, int seq, int     windowSize, struct sockaddr_in serverName) {

    struct packet *sendPacketPtr, sendPacket;
    fd_set writeFdSet;

    sendPacketPtr = &sendPacket;

    sendPacket.flags = type;
    sendPacket.windowsize = windowSize;
    sendPacket.seq = seq;
    sendPacket.id = getpid();

    if (type == NORMAL)
        strcpy(sendPacket.data, data);

    FD_ZERO(&writeFdSet);
    FD_SET(socketFd, &writeFdSet);

    if(select(FD_SETSIZE, NULL, &writeFdSet, NULL, NULL) > 0) {
        if(sendto(socketFd, sendPacketPtr, sizeof(sendPacket), 0, (struct sockaddr     *)&serverName, sizeof(serverName)) < 0) {
            printf("%s packet was not sent\n", typeString);
            perror("Send error");
        } else {
            printf("%s packet was sent\n", typeString);
        }
    }

    return 0;
}

这个循环为它的给定值运行两次。

for (int i = seqBase; i <= seqMax && i < packetNum; i++) {
      sendPacket(socketFd, NORMAL, "DATA", dataArray[i], i, 0, serverName);
}

以及接收功能

struct packet receivePacket (int socketFd, struct sockaddr_in *address, int timeout,     int useTimeout) {

    struct packet buffer;
    fd_set readFdSet;
    struct sockaddr_in dest_addr;

    struct timeval selectTimeout;
    selectTimeout.tv_usec = 0;
    selectTimeout.tv_sec = timeout;

    FD_ZERO(&readFdSet);
    FD_SET(socketFd, &readFdSet);

    socklen_t len = sizeof(dest_addr);

    if(useTimeout == 0) {
        if(select(FD_SETSIZE, &readFdSet, NULL, NULL, NULL) > 0) {
            if(recvfrom(socketFd, &buffer, sizeof(buffer), 0, (struct sockaddr     *)&dest_addr, &len) < 0) {
                perror("Read error");
            }else {
                *address = dest_addr;
            }
        }
    }else {
        if(select(FD_SETSIZE, &readFdSet, NULL, NULL, &selectTimeout) > 0) {
            if(recvfrom(socketFd, &buffer, sizeof(buffer), 0, (struct sockaddr     *)&dest_addr, &len) < 0) {
                perror("Read error");
            }else {
                *address = dest_addr;
            }
        }
    }

    return buffer;

}

从服务器循环调用

receivedPacket = receivePacket(socketFd, &destAddress, 0, 0);
while (receivedPacket.flags == NORMAL) {
      printf("Data received: \"%s\", sequence: %d\n", receivedPacket.data, receivedPacket.seq);
      receivedPacket = receivePacket(socketFd, &destAddress, TIMEOUT, 1);
}

永远运行的输出(因为它一直在重新读取最后一个数据包)是:

Data received: "Packet 0", sequence: 0
Data received: "Packet 1", sequence: 1
Data received: "Packet 1", sequence: 1
Data received: "Packet 1", sequence: 1
Data received: "Packet 1", sequence: 1
........

共有1个答案

松洛华
2023-03-14

>

在您正在检查的while循环中(receivedPacket.flags==NORMAL),如果为NORMAL
则只有您正在打印缓冲区并再次调用该函数。

在“receivePacket”函数中,选择timeout或recvfrom failure(s),明确地将“receivedPacket.flags”更新为otherthen NORMAL,这样,当循环中断时,您将处于正常状态。

 类似资料:
  • 问题内容: 我有一个侦听某些x端口的套接字。 我可以从客户端应用程序将数据发送到套接字,但是无法从服务器套接字获得任何响应。 ..此代码部分从服务器读取数据。 但是,直到关闭服务器上的套接字,我才能从服务器读取任何内容。服务器代码不受我控制,无法对其进行编辑。 如何从客户端代码中克服这个问题。 谢谢 问题答案: 为了在客户端和服务器之间进行通信,必须明确定义协议。 客户端代码将阻塞,直到从服务器收

  • socket_read和socket_recv之间有什么区别?我正在尝试使用PHP套接字,但使用socket_read时收到了以下警告: 请帮帮我!

  • 问题内容: 我目前正在尝试使用boost-asio的套接字API通过网络将一些JSON数据从客户端传输到服务器。我的客户基本上是这样做的: 在服务器端,我可以选择各种功能。我想使用JsonCpp解析接收到的数据。在研究JsonCpp API(http://jsoncpp.sourceforge.net/class_json_1_1_reader.html)时,我发现Reader可以在char数组或

  • 我想从socket读取图像响应,并再次将其传递给另一个socket。但现在我连图像反应都看不懂。

  • 问题内容: 调用一次后如何重新连接到套接字io ? 这是代码 如果我这样做,它会起作用。如果我这样做,它将断开连接。但是,如果我尝试使用重新连接,则连接不再起作用。我如何才能建立连接? 问题答案: 好吧,您可以在这里选择… 首次初始化套接字值时,应使用, 下次(调用一次断开连接后),您应使用再次连接。 所以你的应该是这样的

  • 问题内容: 我们正在使用Oracle作为Web应用程序的数据库。该应用程序在大多数情况下都运行良好,但是出现了“不再需要从套接字读取数据”错误。 我们使用spring,hibernate,并且在我的应用程序上下文文件中有以下数据源。 我不确定这是由于应用程序错误,数据库错误还是网络错误引起的。 我们在oracle日志上看到以下内容 Oracle版本:11.2.0.1.0 问题答案: 对于此类错误,