c++ - 使用 C 进行套接字编程时无法接收或发送整个数据包

标签 c++ c sockets networking network-programming

我一直在尝试通过套接字将数据包从客户端发送到服务器。在一些技巧的帮助下,我的代码取得了相当大的进步。然而,服务器只从客户端接收八个字节并将它们打印在控制台上,而在我的客户端,它似乎已经发送了所有内容。

现在不知道问题是出在发送端还是接收端。我的预感是我的客户端出了问题。有人可以帮忙验证我的假设吗?

客户端代码:

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    data_struct client_data;
    struct packet
    { 
        long int srcID;
        long int destID;
        int pver;
        int profiles;
        int length;
        long int data;
    };


    if (argc < 3) {
        fprintf(stderr,"usage: %s hostname port\n", argv[0]);
        exit(0);
    }
    portno = atoi(argv[2]); //Convert ASCII to integer
    sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor

    if (sockfd < 0) 
        error("ERROR DETECTED !!! Problem in opening socket\n");

    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR DETECTED !!!, no such server found \n");
        exit(0);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address

    serv_addr.sin_family = AF_INET;    
    bcopy((char *)server->h_addr, 
        (char *)&serv_addr.sin_addr.s_addr,
        server->h_length);

    serv_addr.sin_port = htons(portno);

    printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno); 


    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR in connection");

    printf("SUCCESS !!! Connection established \n");

    char buffer[256];
    struct packet *pkt = (struct packet *) buffer;
    char *payload = buffer + sizeof(struct packet);
    long double packet_size;



    printf("Started Creating packet\n");
    pkt->srcID = 01;
    pkt->destID = 02;
    pkt->pver = 03;
    pkt->profiles = 01;
    pkt->length = 16;
    pkt->data = 1; 2; 3; 4; 5; 6; 7; 8;
    {
        if (send(sockfd,pkt,sizeof(packet_size),0) <0)
            printf ("error\n");
        else
            printf ("packet send done");
    }

    return 0;
}

服务器代码:

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno, clilen;
    struct sockaddr_in serv_addr, cli_addr;
    int n;
    char wish;

    long int SrcID;
    long int DestID;
    int Pver;
    int Profiles;
    long int Data;
    int Length;
    char bytes_to_receive;
    int received_bytes;
    struct packet
    { 
        long int srcID;
        long int destID;
        int pver;
        int profiles;
        int length;
        long int data;
    };

    if (argc < 2) {
        fprintf(stderr,"usage: %s port_number1",argv[0]);
        exit(1);
    }
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR DETECTED !!! Problem in opening socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(portno);

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
        error("ERROR DETECTED !!! There was a problem in binding");

    listen(sockfd, 10);
    clilen = sizeof(cli_addr);
    printf("Server listening on port number %d...\n", serv_addr.sin_port); 
    newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);

    if (newsockfd < 0) 
        error("ERROR DETECTED !!! the connection request was not accepted");

    char buffer[256];
    struct packet *pkt = (struct packet *) buffer;
    char *payload = buffer + sizeof(struct packet);
    long double packet_size;

    bytes_to_receive = sizeof(packet_size);
    received_bytes = 0;
    int rc =0;


    while ((rc = recv(newsockfd,pkt,sizeof(packet_size),0)) > 0)
    {
        received_bytes+=rc;
        SrcID = pkt->srcID;
        DestID = pkt->destID;
        Pver = pkt->pver ;
        Profiles = pkt->profiles;
        Length = pkt->length;
        Data = pkt->data;
        printf("Data Received from Client_1 are :\n");
        printf("Source ID: %ld\n", SrcID);
        printf("Destination ID: %ld\n", DestID);
        printf("profile Version: %d\n", Pver);
        printf("No of Profiles: %d\n", Profiles);
        printf("Length: %d\n", Length);
        printf("data : %ld\n", Data);
    }
    if (rc == 0)
    {
        printf("Connection closed by Server\n");
        printf("Bytes received: %d\n",received_bytes);
    }

    if (rc == -1)
    {
        perror("recv");
    }
    {
        if (close(newsockfd) == -1) {
            error("Error closing connection with client 1");
        }

        printf("Connection with client 1 has been closed\n");
    }
    return 0; 

}

我在客户端控制台上看到的输出是:

Client Side:  Client 1 trying to connect with server host 130.191.166.230 on port 1234
SUCCESS !!! Connection established 
Started Creating packet
packet send done

在服务器的控制台上我看到:

Server Side:  Data Received from Client_1 are :
Source ID: 1
Destination ID: 2
profile Version: 0
No of Profiles: 1074462536
Length: 0
data : 0
Connection closed by Server
Bytes received: 8
Connection with client 1 has been closed

最佳答案

首先

recv(newsockfd,pkt,sizeof(packet_size),0)) /* What is packet_size ? */
recv(newsockfd,pkt,sizeof(struct packet),0)) /* You probably mean this. */

这可能会解决您的问题,但是您使用 TCP 套接字的方式存在一些问题。

But at my client side, it prints that it has sent everything

哪里?我没有看到您实际检查发送的字节数。 send(2) 可以在发送少于您要求的数量后返回。

It shows me that only 8 bytes were sent by Client and prints them out.

TCP 是一种面向流的协议(protocol)。您发送字节,它们以相同的顺序到达。因此,当您recv(2)某些内容时,您得到的可能会比您写的少(或多)。因此,以下情况可能是正确的:

client:
send 100 bytes
send 400 bytes

server:
recv 50 bytes
recv 150 bytes
recv 250 bytes
recv 50 bytes

使用 TCP 时,sendrecv 调用的数量不必相同。

关于c++ - 使用 C 进行套接字编程时无法接收或发送整个数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6803468/

相关文章:

linux - 来自/proc 的可能的内部套接字状态列表

c++ - 为什么打印指针地址会触发断点?

c++ - 两步复制省略以在构造函数调用中捕获右值作为实例变量

c++ - 传递对象成员函数作为参数(函数指针)

c - 为什么 strcat 会产生这个错误?

c++ - 为什么 connect() 会给出 EADDRNOTAVAIL?

C++ MFC MDI 在创建时更改子窗口变量

对 fork 调用输出的困惑

c - 套接字死锁

sockets - GNAT.Sockets.Selector_Type 的地址子句是什么