使用“C”在套接字编程中发送数据

时间:2011-07-23 07:29:19

标签: c sockets network-programming

我之前发过一个问题,关于同样的问题,但在这里我想要我的代码指导。使用我尝试创建用于发送数据包的人的提示。我的最大数据包结构以及头和有效负载是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。我想我在服务器代码端的某个地方出错了,但是我无法遵循“序列化”。请用您的输入更新我,这将有很大的帮助。

3 个答案:

答案 0 :(得分:11)

以下是我发现的几个问题:

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

    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;

  5. 中使用long int length;
  6. 我认为服务器中的这种分配也没有意义pkt->srcID = SrcID;,应该是这样的SrcID = pkt->srcID;

答案 1 :(得分:3)

客户端不断发送的问题是因为你只是在一个循环中。随着缩进的修复,很明显发生了什么:

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

答案 2 :(得分:0)

addr_size = sizeof serverAddr;

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