从recvfrom获取缓冲区

时间:2015-12-12 18:06:51

标签: c buffer recvfrom

我试图通过UDP编写tic-tack-toe游戏进行通信。 现在我有代码:

int recv_txt(int sock, struct sockaddr_in *incoming_addr)
{
    char bud[MAX_LENGTH];
    unsigned int incoming_add_len;
    incoming_add_len = sizeof(*incoming_addr);
    if(recvfrom(sock, &buf, MAX_LENGTH, 0 (struct sockaddr*)incoming_addr, &incoming_addr_len) < 0)
    {
         return 0;
    }
    printf("received %s", buf);
    return 1;
}

int main(int argv, char **argc)
{
    /** some code to create socket etc */
    struct sockaddr_in incoming_addr;
    for(;;)
    {
        recv_txt(sock, &incoming_addr);

       //here I would like to create new thread, which will process the buffer from recv_txt and send response;
    }
}

现在我需要从recv_txt获取缓冲区,将其放在这样的结构中:

struct M_s
{
    struct sockaddr_in address;
    char[MAX_LENGTH] buffer;
}

并将其传递给新主题。但是我无法从recv_txt获得缓冲区。我是C的新手,现在我无法很好地使用指针。

感谢您的任何建议。

修改

我尝试过Frankie_c提供的解决方案,但我现在遇到问题printf。 当我尝试main时:

LP_ARGS_STRUCT args = recv_txt(sock)
printf("data from: %s", inet_ntoa(args->address.sin_adrr))

我没有得到任何打印到控制台或收到错误消息。

EDIT2 - 完整代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <pthread.h>

#define SRV_PORT            23456
#define MAX_TXT_LENGTH      1000
#define MAX_ROOMS           1

int sock;

typedef struct args_s
{
    struct sockaddr_in address;
    char buffer[MAX_TXT_LENGTH];
} ARGS_STRUCT, *LP_ARGS_STRUCT;
//typedef struct args_s args;


LP_ARGS_STRUCT recv_txt(int sock)
{
    LP_ARGS_STRUCT args = malloc(sizeof(ARGS_STRUCT));

    //memory error
    if(!args)
    {
        return 1;
    }

    unsigned int incoming_addr_len = sizeof(args->address);

    //incoming_addr_len = sizeof(*incoming_addr);
    if (recvfrom(sock, &args->buffer, MAX_TXT_LENGTH, 0,
                    (struct sockaddr*)&args->address, &incoming_addr_len) < 0)
    {
        free(args);
        return NULL;
    }
    printf("received: %s %s\n", args->buffer, inet_ntoa(args->address.sin_addr));
    return 1;
}

int main(int argv, char **argc)
{
    int i = 0;

    int optval;
    struct sockaddr_in addr, incoming_addr;
    char buffer[MAX_TXT_LENGTH];

    /* create socket */
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0)
    {
        err("socket()");
    }

    /* set reusable flag */
    optval = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

    /* prepare inet address */
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(SRV_PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY); /* listen on all interfaces */
    if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
    {
        err("bind");
    }


    for(;;)
    {


        LP_ARGS_STRUCT args = recv_txt(sock);
        if(!args) continue;
        printf("%s\n", args->buffer);

    }

    return 0;
}

收到包后我得到:

received: Hello 192.168.56.1
Segmentation fault (code dumped)

Process returned 139 (0x8B)

1 个答案:

答案 0 :(得分:1)

对于原始问题,请尝试:

typedef struct M_s
{
    struct sockaddr_in address;
    char[MAX_LENGTH] buffer;
} M_STRUCT, *LP_M_STRUCT;   //Create a typedef for struct

//Modify your function to return a structure pointer and having just socket as par...
LP_M_STRUCT recv_txt(int sock)
{
    LP_M_STRUCT pMs = malloc(sizeof(M_STRUCT));
    if (!pMs)
    {
        //Handle memory error here!
        return NULL;
    }

    unsigned int incoming_add_len = sizeof(pMs->incoming_addr);

    if (recvfrom(sock, &pMs->buffer, MAX_LENGTH, 0, (struct sockaddr *)&pMs->incoming_addr, &incoming_addr_len) < 0)
    {
        free(pMs);      //Release memory
        return NULL;    //Return nothing...
    }

    //If we are here we were successfull.
    //The structure pMs holds all data we need... so give it to caller...
    printf("From %s received %s", inet_ntoa(pMs->address.sin_addr), pMs->buffer);
    return pMs;
}

int main(int argv, char **argc)
{
    /** some code to create socket etc */

    for (;;)
    {
        LP_M_STRUCT pMs = recv_txt(sock);
        if (!pMs)   //Check if we get a sign of life on UDP...
            continue;   //No continue to wait for ...

         //We print values again to check that it is ok...
         printf("From %s received %s", inet_ntoa(pMs->address.sin_addr), pMs->buffer);

        //here create new thread to process the buffer from recv_txt and send response;
        //The new thread code have to release structure memory when done!!!
    }
}

编辑:您的问题是在成功时不返回已分配的结构,并且在失败时不返回NULL 。参见:

LP_ARGS_STRUCT recv_txt(int sock)
{
    LP_ARGS_STRUCT args = malloc(sizeof(ARGS_STRUCT));

    //memory error
    if(!args)
    {
        //return 1;    !!!WRONG!!!
        return NULL;
    }

    unsigned int incoming_addr_len = sizeof(args->address);

    //incoming_addr_len = sizeof(*incoming_addr);
    if (recvfrom(sock, &args->buffer, MAX_TXT_LENGTH, 0,
                    (struct sockaddr*)&args->address, &incoming_addr_len) < 0)
    {
        free(args);
        return NULL;
    }
    printf("received: %s %s\n", args->buffer, inet_ntoa(args->address.sin_addr));
    //return 1;    WRONG! You have to return the allocated struct
    return args;
}