dms代码

转自:http://blog.csdn.net/bao_jinyu/article/details/7554293

/*
 * date            20120510
 * last author:    baojinyu
 * usage:    successful as socket server
 *           successful as dlna media file server
 * */
#include "Neptune.h"
#include "Platinum.h"
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h> /* definations of sa_family structre,htons,INADDR_ANY,... */

#include <arpa/inet.h> /* name ip format */

#include <sys/types.h> /*give the defination of pid_t*/
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#include <stdlib.h>


#include <ctype.h> /* isspace()  */

#define BUFFER_MAX    1024  /* input buffer for commands */
#define TOKEN_MAX     8     /* max number of arguments in buffer */
#define REPLY_MAX     256   /* largest reply allowed */
#define MAX_QUE_CONN_NM    10

NPT_SET_LOCAL_LOGGER("platinum.media.server.file")

//example:NPT_Debug("ERROR: failed to load entity (%d)\n", result);

int sockfd;
static NPT_Flags deviceStartFlag = 0; //服务启动状态为1,服务停止则状态为0
PLT_UPnP upnp;
PLT_DeviceHostReference device;

int init_sock()
{
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1)
    {
        NPT_LOG_INFO("baojinyu---------------create socket error! \n");
        exit(1);
    }
    NPT_LOG_INFO("baojinyu---------------create socket successfully .\n");
    
    return 0;
}

int init_device()
{
    device = new PLT_FileMediaServer(
        "/data/local/1.3gp",//"/data/local/if.mp3", 
        "Platinum UPnP Media Server",
        false,
        "SAMEDEVICEGUID", // NULL for random ID
        (NPT_UInt16)1194);
    NPT_List<NPT_IpAddress> list;
    NPT_CHECK_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(list));
    NPT_String ip = list.GetFirstItem()->ToString();

    device->m_ModelDescription = "Platinum File Media Server";
    device->m_ModelURL = "http://www.plutinosoft.com/";
    device->m_ModelNumber = "1.0";
    device->m_ModelName = "Platinum File Media Server";
    device->m_Manufacturer = "Plutinosoft";
    device->m_ManufacturerURL = "http://www.plutinosoft.com/";

    upnp.AddDevice(device);
    NPT_CHECK_SEVERE(upnp.Start());//Just for test.
    
    return 0;
}

int init()
{
    init_sock();
    init_device();
    return 0;
}

//the following are commands.
static int HandleCmd_dmsStartStop(char **arg, char reply[REPLY_MAX])
{
    if (!deviceStartFlag){
        //start service
        NPT_LOG_INFO("baojinyu------------socket cmd Start。");
        NPT_CHECK_SEVERE(upnp.Start());
        NPT_LOG_INFO("baojinyu------------upnp Start success!");
        deviceStartFlag = 1;
    }
    else{
        //stop service
        NPT_LOG_INFO("baojinyu------------socket cmd stop。");
        upnp.Stop();
        NPT_LOG_INFO("baojinyu------------upnp stop success!");
        deviceStartFlag = 0;
    }
    return deviceStartFlag;

}

struct cmdinfo {
    const char *name;
    unsigned numargs;
    int (*func)(char **arg, char reply[REPLY_MAX]);
};

struct cmdinfo cmds[] = {
    //{ "isMouse",                 1, isMouse },
    //{ "mousePrecision",          1, mousePrecision },
    { "dmsStartStop",                 0, HandleCmd_dmsStartStop },
    //{ "mediaManage",                 1, HandleCmd_mediaManage },
    //{ "serverConfig",                 1, HandleCmd_serverConfig },

};

static int readx(int fd, void *_buf, int count)
{
    char *buf =(char *) _buf;
    int n = 0, r;
    if (count < 0) return -1;
    while (n < count) {
        r = read(fd, buf + n, count - n);
        if (r < 0) {
            if (errno == EINTR) continue;
            NPT_LOG_INFO("read error\n");
            return -1;
        }
        if (r == 0) {
            NPT_LOG_INFO("eof");
            return -1; /* EOF */
        }
        n += r;
    }
    return 0;
}

static int writex(int fd, const void *_buf, int count)
{
    const char *buf =(char *) _buf;
    int n = 0, r;
    if (count < 0) return -1;
    while (n < count) {
        r = write(fd, buf + n, count - n);
        if (r < 0) {
            if (errno == EINTR) continue;
            NPT_LOG_INFO("write error");
            return -1;
        }
        n += r;
    }
    return 0;
}


/* Tokenize the command buffer, locate a matching command,
 * ensure that the required number of arguments are provided,
 * call the function(), return the result.
 */
static int execute(int s, char cmd[BUFFER_MAX])
{
    char reply[REPLY_MAX];
    char *arg[TOKEN_MAX+1];
    unsigned i;
    unsigned n = 0;
    unsigned short count, le_count;
    int ret = -1;

        /* default reply is "" */
    reply[0] = 0;

        /* n is number of args (not counting arg[0]) */
    arg[0] = cmd;
    while (*cmd) {
        if (isspace(*cmd)) {
            *cmd++ = 0;
            n++;
            arg[n] = cmd;
            if (n == TOKEN_MAX) {
                NPT_LOG_INFO("too many arguments");
                goto done;
            }
        }
        cmd++;
    }

    for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) {
        if (!strcmp(cmds[i].name,arg[0])) {
            if (n != cmds[i].numargs) {
                NPT_LOG_INFO("numargs doesnot equal requires arguments ");
            } else {
                ret = cmds[i].func(arg + 1, reply);
            }
            goto done;
        }
    }
    NPT_LOG_INFO("unsupported command");

done:
    if (reply[0]) {
        n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply);
    } else {
        n = snprintf(cmd, BUFFER_MAX, "%d", ret);
    }
    if (n > BUFFER_MAX) n = BUFFER_MAX;
    count = n;

    /* receiver expects count in little-endian order */
    le_count = htole16(count);

//    LOGI("reply: '%s'\n", cmd);
    if (writex(s, &le_count, sizeof(le_count))) return -1;
    if (writex(s, cmd, count)) return -1;
    return 0;
}

int
main(int argc, char** argv)
{
    //setup Neptune logging
    NPT_LogManager::GetDefault().Configure("plist:.level=INFO;.handlers=ConsoleHandler;.ConsoleHandler.colors=off;.ConsoleHandler.filter=42");
    NPT_LOG_INFO("baojinyu---------------media server just begin\n ");    
    init();
    char buf[BUFFER_MAX];
   
    struct sockaddr_in  server_sockaddr, client_sockaddr;
    int sin_size = sizeof(struct sockaddr_in);
        
    /* socket配置 */
    bzero(&server_sockaddr, sizeof(server_sockaddr));
    server_sockaddr.sin_family = AF_INET;    /* 地址族 */
    server_sockaddr.sin_port = htons(7933);/* 端口号 */
    //server_sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");/* 系统会自动填入本机的IP地址 */
    server_sockaddr.sin_addr.s_addr = INADDR_ANY;
    //bzero(&(server_sockaddr.sin_zero),8);/*填充0和struct sockaddr 同样大小*/
    
    int i = 1;    /* 允许重复使用本地地址与套接字进行绑定 */
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, (const char*)&i, sizeof(i));

    //if(bind(sockfd,(struct sockaddr*)&server_sockaddr,len) < 0){
    if(bind(sockfd,(struct sockaddr*)&server_sockaddr, sin_size) == -1){
        NPT_LOG_INFO("baojinyu---------------Bind failure.\n ");
        exit(1);
    }
    NPT_LOG_INFO("baojinyu--------------- Bind successfully.\n ");
    
    /* listen for connections on a socket */
    if(listen(sockfd, MAX_QUE_CONN_NM) == -1){
        NPT_LOG_INFO("baojinyu--------------- Listen failure.\n ");
        exit(1);
    }
    NPT_LOG_INFO("baojinyu--------------- Listen successfully ");

    int client_fd, fd;
    int result;   
    int readflag;

    int maxfd=sockfd;
    fd_set tmp_readfds;
    fd_set readfds;    
    FD_ZERO(&readfds);
    FD_SET(sockfd, &readfds);

    fd_set tmp_writefds;
    fd_set writefds;
    FD_ZERO(&writefds);
    FD_SET(sockfd, &writefds);

    struct timeval timeout; 
    fd_set fdset;
    
    while(true)
    {
        tmp_readfds = readfds;
        tmp_writefds = writefds;
        NPT_LOG_INFO("baojinyu--------------- enter while loop ");    
        timeout={5,0};    
        result = select(maxfd+1, &tmp_readfds, &tmp_writefds, NULL, &timeout);
        if(result == 0)
        {
            NPT_LOG_INFO("baojinyu----------------------Select timeout!---no change happens.\n");
            continue;
        }else if(result == -1)
        {
            NPT_LOG_INFO("baojinyu----------------------Select failure!\n");
            break;
        }
        NPT_LOG_INFO("baojinyu-----------------Select successfully\n");
        
        for(fd=0; fd < FD_SETSIZE; fd++)
        {
            if(FD_ISSET(fd,&tmp_readfds))
            {
                NPT_LOG_INFO("baojinyu-----------------FD_ISSET\n");
                if(fd == sockfd)
                {    //服务端接收客户端连接请求
                    NPT_LOG_INFO("baojinyu-----------------fd == sockfd\n");
                    client_fd = accept(sockfd, (struct sockaddr*)&client_sockaddr, &sin_size);
                    sleep(1);                    
                    if(client_fd > 0)                    
                    {
                        if(client_fd > maxfd){
                            maxfd = client_fd;
                        }
                        FD_SET(client_fd,&readfds);
                        /*
                        NPT_Debug("baojinyu--accept success--------Got connection from %s, port %d,socket %d\n",
                            inet_ntoa(client_sockaddr.sin_addr),ntohs(client_sockaddr.sin_port),client_fd);
                            * */
                        printf("baojinyu--accept success--------Got connection from %s, port %d,socket %d\n",
                            inet_ntoa(client_sockaddr.sin_addr), ntohs(client_sockaddr.sin_port), client_fd);
                        
                    }else {
                        NPT_LOG_INFO("baojinyu-----------------accept failure.\n");
                        break;
                    }
                    
                }else{
                    ioctl(fd,FIONREAD,&readflag);
                    if(readflag == 0){
                        NPT_LOG_INFO("baojinyu----------------readflag == 0  \n");
                        close(fd);
                        FD_CLR(fd,&readfds);
                    }
                    else{
                        bzero(buf, BUFFER_MAX);
                        //处理客户端发来的消息-read size
                        unsigned short count;
                        if (readx(fd, &count, sizeof(count))){
                            NPT_LOG_INFO("baojinyu-------------------failed to read size\n");
                            break;
                        }                                  

                        count = letoh16(count);
                        if ((count < 1) || (count >= BUFFER_MAX)) {
                            //NPT_LOG_INFO("baojinyu-------------------count error!\n");
                            printf("baojinyu--------count error!--count= %d\n",count);
                            break;
                        }
                        if (readx(fd, buf, count)) {
                            NPT_LOG_INFO("baojinyu----------------failed to read command\n");
                            break;
                        }

                        buf[count] = 0;
                        if (execute(fd, buf)) break;
                    
                    }
                }
            } //end of if(FD_ISSET(fd,&tmp_readfds))
        } //end for
    }
    
    for(fd = 0; fd < FD_SETSIZE; fd++)
    {
        close(fd);
        FD_CLR(fd,&readfds);   
    }    

    return 0;
    
}
 


你可能感兴趣的:(server,socket,struct,cmd,command,buffer)