OpenVINOTM,给你看得见的未来!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 学习vxworks程序(一)

共1条 1/1 1 跳转至

学习vxworks程序(一)

菜鸟
2002-05-25 19:30:00    评分
/* * quick-and-dirty HTTP server which allows a remote web browser * to interface with the target machine. It may contain bugs and * misfeatures. The only reason for the existence of this file is * for illustration purpose, to show that it is easy to have a rudimentary * web server style user interface for an embedded device. And it may have * educationable value to some people (questionable). * * Written by Hwa-Jin Bae, bae@mail.com, Piedmont California. * This file is placed in public domain. * * A better, slightly more useful small HTTP server (a port of thttpd) * is also available from "VxHacks" site where this file is originally * distributed. */ #include "vxWorks.h" #include "sys/types.h" #include "ioLib.h" #include "fioLib.h" #include "stdio.h" #include "unistd.h" #include "string.h" #include "usrLib.h" #include "errnoLib.h" #include "hostLib.h" #include "sockLib.h" #include "socket.h" #include "inetLib.h" #include "in.h" #include "selectLib.h" #include "taskLib.h" #include "ctype.h" #include "dirent.h" #include "sys/stat.h" #include "errnoLib.h" #include "fcntl.h" #include "unistd.h" #include "fioLib.h" int vhttpVerbose = 1; #define HTTP_PORT 8080 #define DEBUG 1 /* XXX */ #define MAX_SESSIONS 12 /* 12 concurrent HTTP sessions */ WIND_TCB *vhttp_tasks [MAX_SESSIONS]; WIND_TCB *vhttpd_task = 0; extern int getMyIpAddr(); int vt1(); int vt2(); int vt3(); /* * customizable menu User interface */ struct vtMenu { char * menu_desc; int (* menu_func)(); }; #define MAX_CMDS 3 /* XXX this must match the struct below */ /* list of available commands and callback functions */ struct vtMenu vtCmds[MAX_CMDS] = { { "1. Stuff", vt1 }, { "2. More Stuff", vt2 }, { "3. More and More stuff", vt3 }, }; int vt1() { printf("vt1\n"); return OK; } int vt2() { printf("vt2\n"); return OK; } int vt3() { printf("vt3\n"); return OK; } #ifdef DEBUG static void errorMsg(char *msg) { printf("ERROR: %s, errno 0x%x\n", msg, errnoGet()); } static void infoMsg(char *msg) { printf("INFO: %s\n", msg); } #else #define errorMsg(msg) ; #define infoMsg(msg) ; #endif int vhttpReadInputLine(int sock, char *buffer) { int num; int i; if (ioctl(sock, FIONREAD, &num) < 0){ errorMsg("vhttpReadInputLine: ioctl FIONREAD error"); return -1; } if (num < 1) return -1; for (i=0;;) { char ch; int count; count = read(sock, &ch, 1); if (count < 1) { errorMsg("vhttpReadInputLine: read error"); return -2; } if (ch == (char)0xd) { /* carriage return */ read(sock, &ch, 1); /* eat linefeed */ if (ch != (char)0xa) { errorMsg("vhttpReadInputLine: LF expected but got someting else"); return -2; } break; } buffer[i++] = ch; } buffer[i] = '\0'; return(i); } void vhttpSendErr(int sock, int code, char *msg) { char buf[128]; sprintf(buf, "%d %s\n", code, msg); #ifdef DEBUG printf(buf); #endif write(sock, buf, strlen(buf)); } int vhttpWriteSock(int sock, char *msg) { return (write (sock, msg, strlen(msg))); } void vhttpSendMenu(int sock) { int i; struct vtMenu *mp; char buf[128]; char my_addr[20]; vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); vhttpWriteSock(sock, "text/html\n\n"); vhttpWriteSock(sock, "Welcome to VxHacks, Inc."); vhttpWriteSock(sock, "\n"); vhttpWriteSock(sock, "

Welcome To VxHacks, Inc.

\n"); vhttpWriteSock(sock, "
\n"); vhttpWriteSock(sock, "
\n"); vhttpWriteSock(sock, "

\n"); vhttpWriteSock(sock, "

    \n"); sprintf(my_addr, "%s", inet_ntoa(getMyIpAddr())); for (i = 0, mp = &vtCmds[0]; i < MAX_CMDS; i++, mp++) { vhttpWriteSock(sock, "
  • \n"); sprintf(buf, " %s ", my_addr, HTTP_PORT, i, mp->menu_desc); vhttpWriteSock(sock, buf); } vhttpWriteSock(sock, "
\n"); vhttpWriteSock(sock, "
\n"); vhttpWriteSock(sock, "
\n"); vhttpWriteSock(sock, "\n"); } int vhttpSendHTML(int sock, char *HTML) { int inFd; int status; char *filename; inFd = open (HTML, O_RDONLY, 0); if (inFd < OK) { errorMsg("can't open HTML file"); return (ERROR); } vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); vhttpWriteSock(sock, "text/html\n\n"); status = copyStreams (inFd, sock); return (status); } int vhttpSendGIF(int sock, char *GIF) { int inFd; int status; char *filename; inFd = open (GIF, O_RDONLY, 0); if (inFd < OK) { errorMsg("can't open GIF file"); return (ERROR); } vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); vhttpWriteSock(sock, "image/gif\n\n"); status = copyStreams (inFd, sock); return (status); } int vhttpSendJPEG(int sock, char *JPEG) { int inFd; int status; char *filename; inFd = open (JPEG, O_RDONLY, 0); if (inFd < OK) { errorMsg("can't open JPEG file"); return (ERROR); } vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); vhttpWriteSock(sock, "image/jpeg\n\n"); status = copyStreams (inFd, sock); return (status); } int vhttpProcessURL(int sock, char *URL) { int num; int result; char *suffix; #ifdef DEBUG printf("URL requested <%s>\n", URL); #endif if (strcmp(URL, "/" ) == 0) vhttpSendMenu(sock); else { suffix = strrchr(URL, '.'); if (suffix != 0) { if (strcmp(suffix,".html") == 0) vhttpSendHTML(sock,++URL); else if (strcmp(suffix, ".gif") == 0) vhttpSendGIF(sock,++URL); else if (strcmp(suffix, ".jpeg") == 0) vhttpSendJPEG(sock,++URL); else { vhttpSendMenu(sock); vhttpSendErr(sock, 666, "Unknown URL"); vhttpSendErr(sock, 666, URL); } } else { URL[0] = ' '; /* wipe out leading slash char */ num = atoi(URL); if (num >= 0 && num < MAX_CMDS) { vhttpSendMenu(sock); result = (*vtCmds[num].menu_func)(); if (result == OK) vhttpSendErr(sock, 205, "Command success"); else vhttpSendErr(sock, 905, "Command Failed"); } else { vhttpSendErr(sock, 505, "Invalid menu item URL"); return ERROR; } } } return OK; } int vhttpProcess(int sock, struct sockaddr_in *sinptr) { fd_set read_fdset; fd_set write_fdset; fd_set except_fdset; int finishedHeader=0; char buffer[1024]; char method[20]; char URL[200]; char proto[20]; for (;;) { FD_SET(sock, &read_fdset); FD_SET(sock, &write_fdset); FD_SET(sock, &except_fdset); if (select(64, &read_fdset, &write_fdset, &except_fdset, 0) < 0) continue; if (FD_ISSET(sock, &read_fdset)) { int result; result = vhttpReadInputLine(sock, buffer); if (result < 0) return -1; if (result == 0) { finishedHeader=1; return 0; } if (!finishedHeader) { sscanf(buffer, "%s %s %s", method, URL, proto); #ifdef DEBUG printf("method <%s> URL <%s> proto <%s>\n", method, URL, proto); #endif if (strcmp("HTTP/1.0", proto)) { vhttpSendErr(sock, 501, "Invalid Protocol. Expecting HTTP/1.0"); close(sock); return -1; } if (strcmp(method, "GET") != 0 && strcmp(method, "PUT") != 0) { vhttpSendErr(sock, 501, "Invalid Method. Expecting GET or PUT."); close(sock); return -1; } if (vhttpProcessURL(sock, URL) != OK) { vhttpSendErr(sock, 404, "Invalid URL"); close(sock); return -1; } close(sock); finishedHeader=1; return 0; } } else if (FD_ISSET(sock, &write_fdset)) { ; } else if (FD_ISSET(sock, &except_fdset)) { errorMsg("exception fd set"); } #if 0 taskDelay(2 * 60); #endif } } int vhttpMainLoop(int sock, struct sockaddr_in *sinptr) { int client; char name[25]; static int procNum = 1; int i; int size; for (;;) { WIND_TCB *tcb; size = sizeof(*sinptr); client = accept(sock, (struct sockaddr *)sinptr, &size); if (client < 0) { errorMsg("accept"); return -1; } infoMsg("vhttp: accepted a new client\n"); sprintf(name, "vhttp%d", procNum++); tcb = taskSpawn(name, 101, 0, 1024 * 4, vhttpProcess, client, sinptr, 0, 0, 0, 0, 0, 0, 0, 0); tcb->spare4 = client; for (i = 0; i < MAX_SESSIONS; i++) { if (vhttp_tasks[i] == 0) break; } if (i < MAX_SESSIONS) vhttp_tasks[i] = tcb; else { vhttpSendErr(sock, 501, "Too many sessions"); close(client); return -1; } } return OK; } int vhttpDelete(WIND_TCB *tcb) { int i; if (tcb == vhttpd_task) close(tcb->spare4); /* delete server socket */ for (i = 0; i < MAX_SESSIONS; i++) { if (tcb == vhttp_tasks[i]) { close(tcb->spare4); vhttp_tasks[i] = 0; } } } int vhttpStart() { int sock; struct sockaddr_in sin; struct sockaddr_in *sinptr = &sin; int true = 1; WIND_TCB *tcb; int i; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { errorMsg("socket"); return -1; } if((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&true, sizeof(true))) == -1) { errorMsg("setsockopt"); return -1; } bzero(sinptr, sizeof(*sinptr)); sinptr->sin_family = AF_INET; sinptr->sin_port = htons(HTTP_PORT); sinptr->sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sock, (struct sockaddr *) sinptr, sizeof(*sinptr)) < 0) { errorMsg("bind"); return -1; } if (listen (sock, 5) < 0) { errorMsg("listen"); return -1; } for (i = 0; i < MAX_SESSIONS; i++) vhttp_tasks[i] = 0; tcb = taskSpawn("vHttpD", 100, 0, 2048, vhttpMainLoop, sock, sinptr, 0, 0, 0, 0, 0, 0, 0, 0); tcb->spare4 = sock; vhttpd_task = tcb; taskDeleteHookAdd(vhttpDelete); return OK; } 需要做一些简单修改,就可以在vxworks上run了,只是例子,是用来学习的。



关键词: 学习     vxworks     程序     #include     vh    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]