Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

altera simple socket server troubles

I need to provide TCP/IP connection with speed ~10 Mbit/s

with Cyclone IV Development board.

It provides 10/100/1000 BASE-T Ethernet connection via a Marvell

88E1111 PHY and the FPGA-based Altera Triple Speed Ethernet

MegaCore function in RGMII mode.

I use altera simple socket server example to transmit 1500 bytes payloads.

It tranfer several packets and stop whithout any activity.

Server code:


# include <stdio.h># include <errno.h>
# include <alt_iniche_dev.h># include "ipport.h"# include "libport.h"# include "osport.h"# include "tcpport.h"
# define IP4_ADDR(ipaddr, a,b,c,d) ipaddr = 
    htonl((((alt_u32)(a & 0xff) << 24) | ((alt_u32)(b & 0xff) << 16) | 
          ((alt_u32)(c & 0xff) << 8) | (alt_u32)(d & 0xff)))
# define IPADDR0   192# define IPADDR1   168# define IPADDR2   0# define IPADDR3   200
# define GWADDR0   0# define GWADDR1   0# define GWADDR2   0# define GWADDR3   0
# define MSKADDR0  255# define MSKADDR1  255# define MSKADDR2  255# define MSKADDR3  0
# include "global.h"
int get_mac_addr(NET net, unsigned char mac_addr)
{
   // This is the Altera Vendor ID
   mac_addr = 0x0;
   mac_addr = 0x7;
   mac_addr = 0xed;
   // Reserverd Board identifier
   mac_addr = 0xFF;
   mac_addr = 0x00;
   mac_addr = 0x02;
   printf("Your Ethernet MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n",
         mac_addr,
         mac_addr,
         mac_addr,
         mac_addr,
         mac_addr,
         mac_addr);
   return 0;
}
int get_ip_addr(alt_iniche_dev *p_dev,
                ip_addr* ipaddr,
                ip_addr* netmask,
                ip_addr* gw,
                int* use_dhcp)
{
        IP4_ADDR(*ipaddr, IPADDR0, IPADDR1, IPADDR2, IPADDR3);
        IP4_ADDR(*gw, GWADDR0, GWADDR1, GWADDR2, GWADDR3);
        IP4_ADDR(*netmask, MSKADDR0, MSKADDR1, MSKADDR2, MSKADDR3);
    *use_dhcp = 0;
        printf("Static IP Address is %d.%d.%d.%d\n",
        ip4_addr1(*ipaddr),
        ip4_addr2(*ipaddr),
        ip4_addr3(*ipaddr),
        ip4_addr4(*ipaddr));
    /* Non-standard API: return 1 for success */
    return 1;
}
# define BUF_SIZE  1500 //1500
# define   TASK_STACKSIZE       2048
OS_STK    InitialTaskStk;# define INITIAL_TASK_PRIORITY           5
void work_server()
{
    char buff;
    int socket, len;
    struct sockaddr_in  incoming_addr;
    //server_socket
    int fd_listen, max_socket;
    struct sockaddr_in addr;
    fd_set readfds;
    if ((fd_listen = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
            printf(" Socket creation failed\n");
            while(1);
    }
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9000);
    addr.sin_addr.s_addr = INADDR_ANY;
    if ((bind(fd_listen,(struct sockaddr *)&addr, sizeof(addr))) < 0)
    {
            printf("Bind failed \n");
            while(1);
    }
    if ((listen(fd_listen, 1)) < 0)
    {
            printf("Listen failed\n");
            while(1);
    }
    len = sizeof(incoming_addr);
    FD_ZERO(&readfds);
    FD_SET(fd_listen, &readfds);
    max_socket = fd_listen+1;
    while(1)
    {
            printf("wait accept client\n");
            select(max_socket, &readfds, NULL, NULL, NULL);
            if (FD_ISSET(fd_listen, &readfds))
            {
                    if((socket = accept(fd_listen, (struct sockaddr*)&incoming_addr, &len)) < 0)
                    {
                        printf("accept failed\n");
                        continue;
                    }
                    else
                    {
                        printf("accept OK\n");
                        int bytes_recv, nsize = 0;
                        while((bytes_recv = recv(socket, buff, BUF_SIZE, 0))  != SOCKET_ERROR)
                        {
                             //printf("\n\nbytes_recv = %d\n", bytes_recv);
                             bytes_recv = send(socket, buff, bytes_recv, 0);
                             nsize++;
                             printf("nsize = %d\n", nsize);
                        }
                        printf("\n\n\nSOCKET_ERROR\n\n\n");
                    }
            }
     }
}
TK_OBJECT(to_task);
TK_ENTRY(work_server);
struct inet_taskinfo server_task = {
      &to_task,
      "server",
      work_server,
      6,
      APP_STACK_SIZE,
};
void InitialTask(void *task_data)
{
        alt_iniche_init();
        netmain();
        printf("wait inich\n");
        while (!iniche_net_ready)
            TK_SLEEP(1);
        TK_NEWTASK(&server_task);
        OSTaskDel(OS_PRIO_SELF);// del self task
        while (1);
}
int main (int argc, char* argv, char* envp)
{
    /* Clear the RTOS timer */
      OSTimeSet(0);
      /* SSSInitialTask will initialize the NicheStack
       * TCP/IP Stack and then initialize the rest of the Simple Socket Server example
       * RTOS structures and tasks.
       */
     OSTaskCreateExt(InitialTask,
                                 NULL,
                                 (void *)&InitialTaskStk,
                                 INITIAL_TASK_PRIORITY,
                                 INITIAL_TASK_PRIORITY,
                                 InitialTaskStk,
                                 TASK_STACKSIZE,
                                 NULL,
                                 0);
      /*
       * As with all MicroC/OS-II designs, once the initial thread(s) and
       * associated RTOS resources are declared, we start the RTOS. That's it!
       */
      OSStart();
      while(1); /* Correct Program Flow never gets here. */
      return -1;
}
Client code:


# include <stdio.h># include <string.h># include <winsock2.h># include <windows.h>
# pragma comment(lib, "ws2_32.lib") 
# define PORT 9000# define SERVERADDR "192.168.0.200"
//#define SERVERADDR "127.0.0.1"
DWORD WINAPI RecvMess(LPVOID pmy_sock);
# define COUNT_DATA 256 // 10240 &#1087;&#1086; 1024 = 10 Mb# define NN 1024 // size buffer
int ready = 1;
int main(int argc, char* argv)
{
    DWORD thID;
    char buff;
    printf("TCP DEMO CLIENT\n");
    if (WSAStartup(0x202,(WSADATA *)&buff))
    {
        printf("WSAStart error %d\n", WSAGetLastError());
        return -1;
    }
    SOCKET my_sock;
    my_sock = socket(AF_INET,SOCK_STREAM,0);
    if (my_sock < 0)
    {
        printf("Socket() error %d\n",WSAGetLastError());
        return -1;
    }
    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
    if (inet_addr(SERVERADDR) != INADDR_NONE)
      dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
   
    // &#1089;&#1086;&#1077;&#1076;&#1080;&#1085;&#1077;&#1085;&#1080;&#1077; 
    if (connect(my_sock,(sockaddr *)&dest_addr, sizeof(dest_addr)))
    {
        printf("Connect error %d\n",WSAGetLastError());            
        WSACleanup();
        fgets(buff, sizeof(buff)-1, stdin);
        return -1;
    }
    printf("Connect with %s successfully\n\n", SERVERADDR);
    CreateThread(NULL, NULL, RecvMess, &my_sock, NULL, &thID);
    int nsize = 0;
    for(int i = 0; i < NN; i++)
        buff = (char)(i&0xFF);
    DWORD time = GetTickCount();
    while(nsize < COUNT_DATA)
    {        
        nsize++;
        send(my_sock, buff, NN,0);        
        Sleep(1);
    }
    printf("Wait recv full\n");
    while(ready)
        Sleep(1);
    time = GetTickCount() - time;
    printf("time = %ld\n", time);
    
    fgets(buff, sizeof(buff)-1, stdin);
    closesocket(my_sock);
    WSACleanup();
    return 0;
}
DWORD WINAPI RecvMess(LPVOID pmy_sock)
{
    //FILE *fd;
    char buff;
    int bytes_recv;
    SOCKET my_sock;
    my_sock = *((SOCKET*) pmy_sock);
    /*fd = fopen("recv_file.txt", "wb");
    if(fd == NULL)
    {
        printf("error fopen\n");
        return 1;
    }*/
    int nsize = 0;
    while(nsize < COUNT_DATA)
    {
        bytes_recv = recv(my_sock, buff, NN, 0);
        if (bytes_recv == SOCKET_ERROR)
        {
            printf("error recv\n");
            break;
        }
        /*if(bytes_recv != fwrite(buff, sizeof(char), bytes_recv, fd))
        {
            printf("error fwrite\n");
            break;
        }*/
        nsize++;
    }
    //fclose(fd);
    ready = 0;
    return 0;
}

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    There is a number of reasons which can cause your application to stop.

    First of all you must know if the whole application crashes or it's a matter of a single task;

    use a separate tasks to toggle a signal or blink a LED in order to understand this.

    Also try to keep the send queue limited. I mean, before sending more data, wait until you received a certain amount. For example, if you were transmitting 1,2,3, etc. , don't send N until you have received N - K, where K is the queue limit you choose.

    If this way the system works, then you have a problem with your task stack size or with memory available for managing network packets.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I met the same problem....my program is nearly the same as you posted above.

    I use DM9000A/Nichestack now,and it stop receiving packets after calling send function several times.it blocks in select function,and can't return.

    can you tell me how to solve this problem?