📄 slpsock.c
字号:
/* * Embedded SLP Communication Primitives * * ./software/ch10/emslp/slpsock.c * * mtj@cogitollc.com * */#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/time.h>#include "slpapi.h"#include "slppriv.h"static struct sockaddr_in daSockaddr;int archType = MULTICAST_ARCH;/* * slpInit() * * Perform the high-level SLP initialization (including Active DA * discovery). * */int slpInit( void ){ slpHandleType initHandle; slpParsedServiceReplyType reply; int ret; int slpOpen( slpHandleType * ); /* Perform Active DA Discovery */ slpOpen( &initHandle ); ret = slpRequestService( &initHandle, &reply, "service:directory-agent", "" ); slpClose( &initHandle ); if ( ret != 0 ) { char serviceType[MAX_STRING]; char addrSpec[MAX_STRING]; char port[MAX_STRING]; if (reply.urlCount > 0) { slpParseServiceURL( reply.urls[0].url, serviceType, addrSpec, port ); daSockaddr.sin_family = AF_INET; daSockaddr.sin_addr.s_addr = inet_addr(addrSpec); if (daSockaddr.sin_addr.s_addr == 0xffffffff) { struct hostent *hptr = (struct hostent *)gethostbyname(addrSpec); if (hptr == NULL) { /* Can't figure it out, must be a bad addrSpec */ archType = MULTICAST_ARCH; return 0; } else { struct in_addr **addrs; addrs = (struct in_addr **)hptr->h_addr_list; memcpy(&daSockaddr.sin_addr, *addrs, sizeof(struct in_addr)); } } daSockaddr.sin_port = htons(atoi(port)); if (daSockaddr.sin_port == 0) { daSockaddr.sin_port = htons(PORT_NUMBER); } archType = UNICAST_ARCH; } }#ifdef SLP_DEBUG printf("architecture is %s\n", (archType == UNICAST_ARCH) ? "Unicast" : "Multicast" ); if (archType == UNICAST_ARCH) { printf("DA Host : %s\n", inet_ntoa(daSockaddr.sin_addr) ); printf("DA Port : %d\n", ntohs(daSockaddr.sin_port) ); }#endif return 0;}/* * slpOpen() * * Open an SLP connection. * */int slpOpen( slpHandleType *handle ){ int on=1, ret=-1; struct ip_mreq mreq; struct sockaddr_in localAddr; if (handle == NULL) return -1; bzero( (void *)handle, sizeof(slpHandleType) ); do { handle->sock = socket(AF_INET, SOCK_DGRAM, 0); if (handle->sock < 0) { printf("Can't create socket\n"); break; } ret = setsockopt(handle->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (ret) break; localAddr.sin_family = AF_INET; localAddr.sin_addr.s_addr = htonl( INADDR_ANY ); localAddr.sin_port = htons( 0 ); if (bind(handle->sock, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) { printf("Can't bind to port %d\n", PORT_NUMBER); break; } if (archType == MULTICAST_ARCH) { ret = setsockopt(handle->sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&on, sizeof(on)); if (ret) break; bzero( (void *)&mreq, sizeof(mreq) ); mreq.imr_multiaddr.s_addr = inet_addr( GROUP_IP ); mreq.imr_interface.s_addr = htonl( INADDR_ANY ); ret = setsockopt(handle->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)); if (ret) { printf("can't join multicast group (%d)\n", errno); break; } handle->peerAddr.sin_family = AF_INET; handle->peerAddr.sin_port = htons(PORT_NUMBER); handle->peerAddr.sin_addr.s_addr = inet_addr( GROUP_IP ); } else { memcpy(&handle->peerAddr, &daSockaddr, sizeof(struct sockaddr) ); } } while (0); return ret;}/* * slpSendMessage() * * Send an SLP message through an open SLP handle. * */int slpSendMessage( slpHandleType *handle, slpMsgType *slpMsg ){ int rc; if ((handle == NULL) || (slpMsg == NULL)) return -1; setSlpXID( slpMsg, ++handle->curXid ); rc = sendto( handle->sock, slpMsg->buffer, slpMsg->len, 0, (struct sockaddr *)&handle->peerAddr, sizeof(handle->peerAddr) ); if (rc < 0) printf("slpSendMessage failed (%d)\n", errno); return rc;}/* * slpReceiveMessage() * * Receive an SLP message through an open SLP handle. * */int slpReceiveMessage( slpHandleType *handle, slpMsgType *slpMsg, int timeout ){ fd_set rfds; struct timeval tv; int ret=-1; if ((handle == NULL) || (slpMsg == NULL)) return -1; do { bzero((void *)slpMsg, sizeof(slpMsgType)); FD_ZERO(&rfds); FD_SET(handle->sock, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; ret = select(handle->sock+1, &rfds, NULL, NULL, &tv); if (ret > 0) { if (FD_ISSET(handle->sock, &rfds)) { slpMsg->len = recv( handle->sock, slpMsg->buffer, MAX_BUFFER, 0 ); ret = 0; if (peekXid(slpMsg) == handle->curXid) break; ret = -1; } else { /* Error... */ ret = -1; } } else { /* Timeout */ ret = -1; } } while (timeout--); return ret;}/* * slpClose() * * Close an open SLP connection. * */int slpClose( slpHandleType *handle ){ struct ip_mreq mreq; int ret = -1; if (handle == NULL) return -1; if (handle->sock >= 0) { if ( archType == MULTICAST_ARCH) { bzero( (void *)&mreq, sizeof(mreq) ); mreq.imr_multiaddr.s_addr = inet_addr( GROUP_IP ); mreq.imr_interface.s_addr = htonl( INADDR_ANY ); ret = setsockopt(handle->sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, sizeof(mreq)); } close(handle->sock); handle->sock = -1; } return ret;}/* * Copyright (c) 2002 Charles River Media. All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, is hereby granted without fee provided * that the following conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * 3. Neither the name of Charles River Media nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY CHARLES RIVER MEDIA AND CONTRIBUTERS * 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CHARLES * RIVER MEDIA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARAY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -