qemu提示thread:tcpip stack overflow栈溢出

img

基于rt-thread的qemu虚拟开发板工程,编译运行后,env提示thread:tcpip stack overflow
大概是什么原因导致?,这里给出我的工程代码


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <rtthread.h>
#include <netdb.h>
#include <sys/types.h>
#include <dfs_posix.h>
#include <limits.h>
#include <unistd.h>

#define MAX_INPUT_SIZE 254
#define SERVER_IP "192.168.101.200" //主机FTP ip

#define SERVER_PORT 2123
#define DATA_PORT 2048
#define FILEBUF_SIZE 1024
#define TYPE_I 0
#define TYPE_A 1

int TYPE = 0;
const char *MODE[] = {"BINARY", "ASCII"};
char buffer[FILEBUF_SIZE];
char line_in[MAX_INPUT_SIZE + 1];
char *server_ip, *local_ip;
char port_addr[24] = "";
int server_port, local_port;
int server_sock, client_sock = -1, data_sock;
int z = 0;

static struct sockaddr_in server_addr, client_addr, data_addr;
static struct hostent *server_host;

#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       (1024*20)
#define THREAD_TIMESLICE        5

/*
Search through str looking for what. Replace any what with
the contents of by. Do not let the string get longer than max_length.
*/
int replace(char *str, char *what, char *by, int max_length);

//send msg to server
void send_msg(char *command, char *msg, int flag);

//functions
void help_info();
void user_login();
void command_quit();
void command_syst();
void command_type();
void command_pwd();
void command_cd();
int command_port();
int data_conn(char *ip, int port);
void command_list();
void command_get(char *filename);
void command_put(char *filename);
int ftpSession();

static rt_thread_t tid1 = RT_NULL;
static void thread1_entry(void *parameter) {
    ftpSession(1, 0);
    rt_thread_mdelay(1000);
}

void ftpthread() {
    tid1 = rt_thread_create("thread1",
                            thread1_entry, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);
}

int ftpSession() {

//    if (argv == 1) {
//        server_ip = SERVER_IP;
//        server_port = SERVER_PORT;
//    } else if (argv == 2) {
//        server_ip = argc[1];
//        server_port = SERVER_PORT;
//    } else if (argv == 3) {
//        server_ip = argc[1];
//        server_port = atoi(argc[2]);
//    }

    server_ip = SERVER_IP;
    server_port = SERVER_PORT;

    //连接到服务器
    server_host = lwip_gethostbyname(server_ip);
    if (server_host == (struct hostent *)NULL) {
        rt_kprintf(">gethostbyname failed\n\n");
        return (-1);
    }

    //建立端口连接
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    //memcpy(&server_addr.sin_addr, server_host->h_addr, server_host->h_length);
    server_addr.sin_addr = *((struct in_addr *)server_host->h_addr);
    server_addr.sin_port = htons(server_port);
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    //get the socket
    server_sock = lwip_socket(PF_INET, SOCK_STREAM, 0);
    if (server_sock < 0) {
        rt_kprintf(">error on socket()\n\n");
        return (-1);
    }
    rt_thread_mdelay(500);

    //连接到服务器
    if (lwip_connect(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        rt_kprintf(">error on connect()\n");
        lwip_close(server_sock);
        return (-1);
    }

    //成功连接到ftp服务器
    rt_kprintf(">Connected to %s:%d\n", server_ip, server_port);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n\n", buffer);
    //printf("z = %d, buffer is '%s'\n",z,buffer);
    //login
    user_login();
    command_pwd();
    command_list();

    command_get("../tmp/ftp.rar");
    //command_put("E:\\devC++\\202255953.bin");

#if 1
    while (1) {
        //rt_kprintf(">");
        //fgets(line_in, MAX_INPUT_SIZE, stdin);
        //line_in[strlen(line_in)-1] = '\0';
        if (strncmp("quit", line_in, 4) == 0) {
            command_quit();
            break;
        } else if ((strncmp("?", line_in, 1) == 0) || (strncmp("help", line_in, 4) == 0)) {
            help_info();
        } else if (strncmp("syst", line_in, 4) == 0) {
            command_syst();
        } else if (strncmp("type", line_in, 4) == 0) {
            command_type();
        } else if (strncmp("pwd", line_in, 3) == 0) {
            command_pwd();
        } else if (strncmp("cd", line_in, 2) == 0) {
            command_cd();
        } else if (strncmp("port", line_in, 4) == 0) {
            command_port();
        } else if ((strncmp("ls", line_in, 4) == 0) || (strncmp("dir", line_in, 3) == 0)) {
            command_list();
        } else if (strncmp("get", line_in, 3) == 0) {
            command_get(&line_in[4]);
        } else if (strncmp("put", line_in, 3) == 0) {
            command_put(&line_in[4]);
        }
        rt_thread_mdelay(1000);
    }
#endif
    lwip_close(server_sock);
    return 0;
}


/*
在str中搜索要查找的内容。将任何what替换为by的内容。不要让字符串超过max\u长度。
*/
int replace(char *str, char *what, char *by, int max_length) {
    char *foo, *bar = str;
    int i = 0;
    int str_length, what_length, by_length;

    /* 进行完整性检查 */
    if (! str) return 0;
    if (! what) return 0;
    if (! by) return 0;

    what_length = strlen(what);
    by_length = strlen(by);
    str_length = strlen(str);

    foo = strstr(bar, what);
    /* keep replacing if there is somethign to replace and it
    will no over-flow
    */
    while ( (foo) && ( (str_length + by_length - what_length) < (max_length - 1) ) ) {
        bar = foo + strlen(by);
        memmove(bar, foo + strlen(what), strlen(foo + strlen(what)) + 1);
        memcpy(foo, by, strlen(by));
        i++;
        foo = strstr(bar, what);
        str_length = strlen(str);
    }
    return i;
}

//send msg to server
void send_msg(char *command, char *msg, int flag) {
    char reply[MAX_INPUT_SIZE + 1];
    if (flag == 0)
        sprintf(reply, "%s\r\n", command);
    else
        sprintf(reply, "%s %s\r\n", command, msg);

    lwip_write(server_sock, reply, strlen(reply));
    rt_kprintf("%d-->%s", strlen(reply), reply);
    return;
}

void help_info() {
    rt_kprintf("?\tcd\tdir\tls\n");
    rt_kprintf("help\tsyst\ttype\tport\n");
    rt_kprintf("pwd\tget\tput\tquit\n");
}

void user_login() {
    rt_kprintf(">Name: ");

    //fgets(line_in, MAX_INPUT_SIZE, stdin);
    //line_in[strlen(line_in)-1] = '\0';
    send_msg("USER", "tonghoujian", 1);

    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);
    //printf("z = %d, buffer is '%s'\n\n",z,buffer);
    //if(strncmp("331", buffer, 3) == 0)
    {
        rt_kprintf(">Password:");
        //fgets(line_in, MAX_INPUT_SIZE, stdin);
        //line_in[strlen(line_in)-1] = '\0';
        send_msg("PASS", "thj13657278648", 1);

        z = lwip_read(server_sock, buffer, sizeof(buffer));
        buffer[z - 2] = 0;
        rt_kprintf("%s\n", buffer);
        //printf("z = %d, buffer is '%s'\n\n",z,buffer);
    }
    line_in[0] = 0;
    command_syst();
    return;
}

void command_syst() {
    send_msg("SYST", "", 0);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);
}

void command_quit() {
    send_msg("QUIT", "", 0);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n\n", buffer);
}

void command_type() {
    char msg[2];
    msg[1] = 0;
    if (strncmp("ascii", &line_in[5], 5) == 0) {
        msg[0] = 'A';
        TYPE = TYPE_A;
    } else if (strncmp("binary", &line_in[5], 6) == 0) {
        msg[0] = 'I';
        TYPE = TYPE_I;
    }
    send_msg("TYPE", msg, 1);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);
}

void command_pwd() {
    send_msg("PWD", "", 0);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n\n", buffer);
}

void command_cd() {
    send_msg("CWD", &line_in[3], 1);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n\n", buffer);
}

int command_port() {
#if 0
    //主动模式客户端配置
    if (client_sock < 0) {
        struct sockaddr_in local_addr;
        socklen_t local_addr_len = sizeof local_addr;
        memset(&local_addr, 0, sizeof(local_addr));
        if (lwip_getsockname(server_sock, (struct sockaddr *)&local_addr, &local_addr_len) != 0) {
            rt_kprintf("error when trying to get the local addr\n");
            return -1;
        }
        local_ip = inet_ntoa(local_addr.sin_addr);
        local_port = local_addr.sin_port;
        rt_kprintf("local addr  %s:%d\n", local_ip, local_port);
        char client_port[8] = "";
        sprintf(client_port, "%d.%d", (int)(local_port / 256), (int)(1 + local_port - 256 * (int)(local_port / 256)));
        sprintf(port_addr, "%s.%s", local_ip, client_port);
        replace(port_addr, ".", ",", 24);

        if (data_conn(local_ip, local_port + 1) == -1) return -1;
    }

    send_msg("PORT", port_addr, 1);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);

    //accept an request
    socklen_t data_addr_len = sizeof data_addr;
    memset(&data_addr, 0, sizeof data_addr);
    data_sock = lwip_accept(client_sock, (struct sockaddr *)&data_addr, &data_addr_len);
    if (data_sock < 0) {
        //close(client_sock);
        rt_kprintf("data_sock accept failed!\n");
        return -1;
    }
    //close(client_sock);
#endif
    //被动模式客户端配置
    send_msg("PASV", "", 1);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n\n", buffer);
    char *find;
    //char *ipaddr=NULL;
    int dataPort;
    int a, b, c, d;
    int pa, pb;
    find = strrchr(buffer, '(');
    sscanf(find, "(%d,%d,%d,%d,%d,%d)", &a, &b, &c, &d, &pa, &pb);
    //sprintf(ipaddr, "%d.%d.%d.%d", a, b, c, d);
    dataPort = pa * 256 + pb;
    rt_kprintf("dataPort%d\n", dataPort);
    memset(&data_addr, 0, sizeof(data_addr));
    data_addr.sin_family = AF_INET;
    data_addr.sin_port = htons(dataPort);
    data_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    rt_memset(&(data_addr.sin_zero), 0, sizeof(data_addr.sin_zero));

    data_sock = lwip_socket(PF_INET, SOCK_STREAM, 0);
    if (data_sock < 0) {
        rt_kprintf(">error on data_sock()\n");
        return (-1);
    }
    if (lwip_connect(data_sock, (struct sockaddr *)&data_addr, sizeof(data_addr)) < 0) {
        rt_kprintf(">error on connect()\n\n");
        lwip_close(data_sock);
        return (-1);
    }
    //connect to the ftp data_sock successful
    rt_kprintf(">Connected to data_connection %s:%d\n\n", SERVER_IP, dataPort);

    return 0;
}

int data_conn(char *ip, int port) {
    client_sock = lwip_socket(PF_INET, SOCK_STREAM, 0);
    if (client_sock == -1) {    //create socket failed
        close(client_sock);
        rt_kprintf("data socket() failed");
        return -1;
    }
    //configure server address,port
    memset(&client_addr, 0, sizeof(client_addr));
    socklen_t client_addr_len = sizeof client_addr;
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(port);
    //client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    client_addr.sin_addr.s_addr = inet_addr(ip);
    if (client_addr.sin_addr.s_addr == INADDR_NONE) {
        rt_kprintf("INADDR_NONE");
        return -1;
    }

    //bind
    z = lwip_bind(client_sock, (struct sockaddr *)&client_addr, client_addr_len);
    if (z == -1) {
        lwip_close(client_sock);
        perror("data_sock bind() failed\n");
        return -1;
    }

    //listen
    z = lwip_listen(client_sock, 1);
    if (z < 0) {
        close(client_sock);
        rt_kprintf("data_sock listen() failed!\n");
        return -1;
    }
    rt_kprintf("data conn listening...\n\n");
    return 0;
}

void command_list() {
    unsigned char databuf[100];
    int bytes = 0, bytesread = 0;

    send_msg("TYPE", "A", 1);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);
    TYPE = TYPE_A;
    rt_kprintf("TYPE%d\n", TYPE);
    if (command_port() == -1) return;
    send_msg("LIST", "", 0);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);
#if 1
    /* Read from the socket and write to stdout */
    while ((bytes = lwip_read(data_sock, databuf, sizeof(databuf)) > 0)) {
        //write(fileno(stdout), databuf, bytes);
        rt_kprintf("%s", databuf);
        bytesread += bytes;
    }
    //关闭socket连接
    lwip_close(data_sock);
#endif
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);
}

void command_get(char *filename) {
    int outfile;
    short file_open = 0;
    char *file_get = "text.txt";
    unsigned char databuf[FILEBUF_SIZE];
    int bytes = 0, bytesread = 0;

    if (command_port() == -1) return;
    send_msg("RETR", filename, 1);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);

    /* Read from the socket and write to the file */
    while ((bytes = lwip_read(data_sock, databuf, FILEBUF_SIZE)) > 0) {
        if (file_open == 0) {
            /* Open the file the first time we actually read data */
            if ((outfile = open(file_get, O_WRONLY | O_CREAT)) == 0) {
                rt_kprintf("fopen failed to open file");
                lwip_close(data_sock);
                return;
            }
            file_open = 1;
        }
        write(outfile, databuf, bytes);
        bytesread += bytes;
    }

    /* Close the file and socket */
    if (file_open != 0) close(outfile);
    lwip_close(data_sock);

    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);

    rt_kprintf("%d bytes get.\n\n", bytesread);
}

void command_put(char *filename) {
    int infile;
    unsigned char databuf[FILEBUF_SIZE] = "";
    int bytes = 0, bytessend = 0;

    infile = open(filename, O_RDONLY);
    if (infile == 0) {
        rt_kprintf("fopen() failed");
        //close(data_sock);
        return;
    }

    if (command_port() == -1) return;
    send_msg("STOR", filename, 1);
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);

    while ((bytes = read(infile, databuf, FILEBUF_SIZE)) > 0) {
        //rt_kprintf("read infile\n");
        rt_kprintf("bytes = %d\n", bytes);
        if (TYPE == TYPE_A) {
            //rt_kprintf("lwip_write TYPE_A\n");
            //replace((char *)databuf, "\r\n", "\n", FILEBUF_SIZE-1);
            //replace((char *)databuf, "\n", "\r\n", FILEBUF_SIZE-1);
            lwip_write(data_sock, databuf, sizeof(databuf));
        } else if (TYPE == TYPE_I) {
            rt_kprintf("lwip_write TYPE_I\n\n");
            lwip_write(data_sock, (const char *)databuf, bytes);
        }

        bytessend += bytes;
        memset(&databuf, 0, FILEBUF_SIZE);
    }
    memset(&databuf, 0, FILEBUF_SIZE);
    rt_kprintf("close(infile)\n\n");
    close(infile);
    lwip_close(data_sock);
    rt_kprintf("lwip_read server_sock\n");
    z = lwip_read(server_sock, buffer, sizeof(buffer));
    buffer[z - 2] = 0;
    rt_kprintf("%s\n", buffer);

    rt_kprintf("%d bytes send\n\n", bytessend);
    return;
}

#if 1
int main(void) {
    int count = 1;

    ftpSession();
    while (count++) {
        //LOG_D("Hello RT-Thread!");
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}
#endif

MSH_CMD_EXPORT_ALIAS(ftpthread, ftp, ftp.);