【问题标题】:Sending Data in socket programming using "C"使用“C”在套接字编程中发送数据
【发布时间】:2011-07-23 07:29:19
【问题描述】:

我之前发布了一个关于相同的问题,但在这里我需要有关我的代码的指导。使用我尝试创建的人的提示来发送数据包。我的最大数据包结构以及标头和有效负载为 16 个字节。如果可能,请浏览发送和接收代码并建议我哪里出错了。基本上我的客户端一直在向服务器发送数据,只是没有结束,服务器没有显示结果。

客户:

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    struct packet
    { 
        long int srcID;
        long int destID;
        long int pver;
        long int profiles;
        char 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[128];
    struct packet *pkt = (struct packet *) buffer;
    char *payload = buffer + sizeof(struct packet);
    long int packet_size;

    printf("Started Creating packet\n");
    pkt->srcID = 0x01;
    pkt->destID = 0x02;
    pkt->pver = 0x01;
    pkt->profiles = 0x01;
    pkt->length = 128;
    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;
    long int Pver;
    long int Profiles;
    long int Data;
    char Length;
    char bytes_to_receive;
    char received_bytes;
    struct packet
    { 
        long int srcID;
        long int destID;
        long int pver;
        long int profiles;
        char 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[128];
    struct packet *pkt = (struct packet *) buffer;
    char *payload = buffer + sizeof(struct packet);
    long int packet_size;

    bytes_to_receive = sizeof(pkt);
    received_bytes = 0;

    if (recv(newsockfd, pkt, sizeof(pkt), 0) < 0)
        error("ERROR DETECTED !!! There was a problem in reading the data");
    else
    { 
        do {
            received_bytes += (buffer + received_bytes, bytes_to_receive - received_bytes);
        } while (received_bytes != bytes_to_receive);

        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: %l\n", SrcID);
        printf("Destination ID: %l\n", DestID);
        printf("profile Version: %l\n", Pver);
        printf("No of Profiles: %l\n", Profiles);
        printf("Length: %l\n", Length);
        printf("data : %l\n", Data);
    }
    if (close(newsockfd) == -1) {
        error("Error closing connection with client 1");
    }

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

服务器没有显示任何 o/p。客户说它已经发送了数据包。在编译服务器代码时,我看到四个警告,说明服务器代码中所有 printf 语句的格式为未知转换类型字符 0xa。我想我在服务器代码端的某个地方出错了,但我无法遵循“序列化”。请用您的输入更新我,这将有很大帮助。

【问题讨论】:

  • 你不应该发送payload而不是pkt吗?

标签: c sockets network-programming


【解决方案1】:

这是我发现的几个问题:

  1. 您的客户一直在发送包裹,因为它处于无限状态 环形。
  2. 您传递了错误的 recv 函数的 len 参数。现在 你通过 sizeof(packet_size) 等于 sizeof(long int) (4 32 位操作系统上的字节),但可能您的意图是使用 sizeof(packet)(16 字节)。
  3. 你不检查有多少字节 真正由 recv 函数读取。使用 TCP,您无法保证 您读取了所有 16 个字节的结构数据包。所以时不时你 可以读取更少的字节,您的数据包将不完整。这是一个 一些伪代码中的示例你应该如何接收整个数据包:

    bytes_to_receive = sizeof(packet)
    received_bytes = 0;
    do {
        received_bytes += recv(buffer + received_bytes, bytes_to_receive - received_bytes)
    } while (received_bytes != bytes_to_receive)
    
  4. 您在客户端和服务器中的结构 packet 不同。在一个你使用char length; 在第二个long int length;

  5. 我认为服务器中的这种分配也没有意义pkt-&gt;srcID = SrcID;,应该是这样的SrcID = pkt-&gt;srcID;

【讨论】:

  • +1。除非他检查 recv() 的结果为零,否则他也不可能检测到 EOS。
  • 合并您的建议后,我看到一个错误:server.c:85:5: error: too little arguments to function ârecvâ /usr/include/sys/socket.h:148:16: 注意:在这里声明我的代码的第 85 行是 do { received_bytes += recv(buffer + received_bytes, bytes_to_receive - received_bytes); } while (received_bytes != bytes_to_receive);
  • 在伪代码中,recv 函数的参数较少,对……这就是我得到的错误。这段代码应该放在哪里或者所有的修改都需要做什么..
【解决方案2】:

客户端不断发送的问题是因为您只是将其置于循环中。缩进固定后,发生了什么就很清楚了:

while (1)
{
    if (send(sockfd,pkt,sizeof(packet_size),0) <0)
        printf ("error\n");
    else
        printf ("packet send done");
}

【讨论】:

  • 我在服务器端看不到任何打印内容........以前我被告知 2 应用序列化,你能指导我看我的代码哪些部分 r 不在适当的位置.. .....谢谢
【解决方案3】:
addr_size = sizeof serverAddr;

connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    相关资源
    最近更新 更多