简体   繁体   English

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

[英]Sending Data in socket programming using “C”

I had earlier posted a question, regarding same, but over here i want guidance for my code.我之前发布了一个关于相同的问题,但是在这里我想要我的代码的指导。 Using the tips from people I have tried to create for sending a packet.使用我尝试创建的人的提示来发送数据包。 My max packet structure alongwith header and payload is of 16 bytes.Kindly if possible glance through the sending and receiving code and suggest where i am going wrong.我的最大数据包结构以及 header 和有效负载为 16 个字节。如果可能,请浏览发送和接收代码并建议我哪里出错了。 Basically my client keeps sending data to server,it just doesn't end and server doesn't show results.基本上我的客户一直在向服务器发送数据,它只是没有结束,服务器没有显示结果。

Client:客户:

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;
}

Server:服务器:

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; 
}

The server is not showing any o/p.服务器没有显示任何 o/p。 Client says it has send the packet.客户说它已经发送了数据包。 While compiling the server code i see four warnings saying unknown conversion type characters 0xa in format for all the printf statements in server code.在编译服务器代码时,我看到四个警告,说明服务器代码中所有 printf 语句的格式为未知转换类型字符 0xa。 I guess I am going wrong somewhere in the server code side, but I am not able to follow the "serialization".我想我在服务器代码端的某个地方出错了,但我无法遵循“序列化”。 Please update me with your inputs, it would be of great help.请用您的输入更新我,这将有很大帮助。

Here is couple of issues that I found:这是我发现的几个问题:

  1. Your client keep sending packages because it is in infinite while loop.您的客户一直在发送包裹,因为它处于无限循环中。
  2. You passed wrong len parameter of recv function.您传递了错误的 recv function 的 len 参数。 Right now you pass sizeof(packet_size) which is equal to sizeof(long int) (4 bytes on 32 bit OS), but probably your intension was to use sizeof(packet) (16 bytes).现在您传递的 sizeof(packet_size) 等于 sizeof(long int) (在 32 位操作系统上为 4 个字节),但您的意图可能是使用 sizeof(packet) (16 个字节)。
  3. You don't check how many bytes were truly read by recv function.您没有检查 recv function 真正读取了多少字节。 With TCP you don't have guaranties that you read all 16 bytes of struct packet.使用 TCP 您不能保证您读取了所有 16 个字节的结构数据包。 So from time to time you could read less bytes and your packet will be incomplete.因此,有时您可以读取更少的字节,并且您的数据包将不完整。 Here is an example in some pseudo code how you should receive whole 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. Your struct packet in client and server is different.您在客户端和服务器中的结构packet是不同的。 In one you use char length;在一个中,您使用char length; in second long int length;在第二个long int length;

  5. I think also this kind of assignments in server make no sense pkt->srcID = SrcID;我认为服务器中的这种分配也没有意义pkt->srcID = SrcID; and should be something like this SrcID = pkt->srcID;应该是这样的SrcID = pkt->srcID;

The problem with the client continually sending is because you simply have it in a loop.客户端不断发送的问题是因为您只是将其置于循环中。 With indentation fixed, it becomes clear what has happened:缩进固定后,发生了什么就很清楚了:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM