转自: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; }