⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketun.cc

📁 分布式仿真 开放源码
💻 CC
字号:
// ----------------------------------------------------------------------------// CERTI - HLA RunTime Infrastructure// Copyright (C) 2002, 2003  ONERA//// This file is part of CERTI-libCERTI//// CERTI-libCERTI is free software ; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public License// as published by the Free Software Foundation ; either version 2 of// the License, or (at your option) any later version.//// CERTI-libCERTI is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY ; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this program ; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA//// $Id: SocketUN.cc,v 3.9 2003/08/20 18:40:02 breholee Exp $// ----------------------------------------------------------------------------#include <config.h>#include "SocketUN.hh"#include "RTItypes.hh"#include <assert.h>#include <iostream>#include <unistd.h>#include <strings.h>#include <sstream>#include <stdio.h>#include <errno.h>#include <sys/un.h>using std::ostringstream ;using std::cout ;using std::endl ;namespace certi {#define MAX_ATTEMPTS 3// ----------------------------------------------------------------------------//! Called by server to open the socket and wait for the connection.void SocketUN::acceptUN(){    struct sockaddr_un nom_client, nom_serveur ;    socklen_t lg_nom ;    pD->Out(pdInit, "Opening Server UNIX Socket.");    // Socket    if ((sock_connect = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)        error("socket");    pD->Out(pdInit, "Server has got UNIX Socket FpD->");    // Set Server address    memset(&nom_serveur, 0, sizeof(nom_serveur));    nom_serveur.sun_family = AF_UNIX ;    if (strlen(NOM_FICHIER_SOCKET) > 90)        throw RTIinternalError("NOM_FICHIER_SOCKET too long.");    ostringstream socket_name ;    socket_name << NOM_FICHIER_SOCKET << '.' << getpid();    name = socket_name.str();    strcpy(nom_serveur.sun_path, socket_name.str().c_str());    // Bind    if (bind(sock_connect, (struct sockaddr*)&nom_serveur,             sizeof(struct sockaddr_un)) < 0)        error("bind");    pD->Out(pdInit, "Server: Bind succeeded, now listening.");    // Listen    if (listen(sock_connect, 10) == -1)        error("listen");    pD->Out(pdInit, "Server: Listen returned, now accepting.");    // Accept    lg_nom = sizeof(struct sockaddr_un);    if ((_socket_un = accept(sock_connect,                             (struct sockaddr*)&nom_client,                             &lg_nom)) < 0)        // HPUX:(int*) &lg_nom)) < 0)        error("accept");    pD->Out(pdInit, "Server: Accept OK, server running.");    _est_init_un = RTI_TRUE ;    _est_serveur = RTI_TRUE ;}// ----------------------------------------------------------------------------//! Called by client to connect.void SocketUN::connectUN(pid_t Server_pid){    int Attempt = 0 ;    int Result ;    struct sockaddr_un nom_serveur ;    while (Attempt < MAX_ATTEMPTS) {        pD->Out(pdInit, "Opening Client UNIX Socket.");        // Socket        if ((_socket_un = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)            error("socket");        pD->Out(pdInit, "Client has got UNIX Socket FpD->");        // Clear and set Server adress        memset(&nom_serveur, 0, sizeof(nom_serveur));        nom_serveur.sun_family = AF_UNIX ;        if (strlen(NOM_FICHIER_SOCKET) > 90)            throw RTIinternalError("NOM_FICHIER_SOCKET too long.");        ostringstream socket_name ;        socket_name << NOM_FICHIER_SOCKET << '.' << Server_pid ;        name = socket_name.str();        strcpy(nom_serveur.sun_path, socket_name.str().c_str());        // Connect        Result = connect(_socket_un,                         (struct sockaddr*) &nom_serveur,                         sizeof(struct sockaddr_un));        pD->Out(pdInit, "Client: Connect returned %d.", Result);        // Success ? Yes->break        if (Result == 0)            break ;        // Failure        printf("SocketUN: Connect, attempt #%d out of %d failed\n",               Attempt + 1, MAX_ATTEMPTS);        sleep(1);        Attempt ++ ;    }    pD->Out(pdInit, "Client: Done.");    if (Result != -1)        _est_init_un = RTI_TRUE ;    else        error("Connect");}// ----------------------------------------------------------------------------//! Does not open the socket, see Init methods.SocketUN::SocketUN(SignalHandlerType theType)    : _socket_un(0), _est_serveur(RTI_FALSE), _est_init_un(RTI_FALSE),      HandlerType(theType), SentBytesCount(0), RcvdBytesCount(0){#ifdef SOCKUN_BUFFER_LENGTH    RBLength = 0 ;#endif    pD = new pdCDebug("SOCKUN", "(SocketUN) - ");    pD->Out(pdInit, "UNIX Socket created.");}// ----------------------------------------------------------------------------//! Close the socket.SocketUN::~SocketUN(){    if (_est_init_un) {        close(_socket_un);        if (_est_serveur == RTI_TRUE)            close(sock_connect);        unlink(name.c_str());        if (_est_serveur == RTI_TRUE)            pD->Out(pdTerm, "Server: Closed all sockets.");        else            pD->Out(pdTerm, "Client: Closed all sockets.");    }    delete pD ;#ifdef RTI_PRINTS_STATISTICS    cout << "Unix Socket " ;    cout.width(2);    cout << _socket_un << " : total = " ;    cout.width(9);    cout << SentBytesCount << "b sent " << endl ;    cout << "Unix Socket " ;    cout.width(2);    cout << _socket_un << " : total = " ;    cout.width(9);    cout << RcvdBytesCount << "b received" << endl ;#endif}// ----------------------------------------------------------------------------//! send.voidSocketUN::send(void *buffer, unsigned long size)    throw (NetworkError, NetworkSignal){    long sent = 0 ;    unsigned long total_sent = 0 ;    assert(_est_init_un);    pD->Out(pdTrace, "Beginning to send UN message...");    while (total_sent < size) {        sent = write(_socket_un, (char *) buffer + total_sent, size - total_sent);        if (sent > 0) {            total_sent += sent ;            pD->Out(pdTrace, "Sent %ld bytes out of %ld.", total_sent, size);        }        else {            if (sent < 0) {                pD->Out(pdExcept, "Error while sending on UN socket.");                // Incoming Signal                if (errno == EINTR) {                    if (HandlerType == stSignalInterrupt) throw NetworkSignal();                    else pD->Out(pdExcept, "EmettreUN ignoring signal interruption.");                }                // Other errors                else {                    perror("UN Socket(EmettreUN) : ");                    throw NetworkError("Error while sending UN message.");                }            }            if (sent == 0) {                pD->Out(pdExcept, "No data could be sent, connection closed?.");                throw NetworkError("Could not send any data on UN socket.");            }        }    }    SentBytesCount += total_sent ;}// ----------------------------------------------------------------------------//! error.void SocketUN::error(const char *msg){    char m[100] ;    m[0] = 0 ;    strcat(m, "SocketUN: ");    strcat(m, msg);    perror(m);    exit(-1);}// ----------------------------------------------------------------------------/*! Return RTI_TRUE if any data as already been read from the system socket  and is waiting in the internal buffer, else RTI_FALSE.*/Boolean SocketUN::isDataReady(){#ifdef SOCKUN_BUFFER_LENGTH    if (RBLength > 0)        return RTI_TRUE ;    else        return RTI_FALSE ;#else    return RTI_FALSE ;#endif}// ----------------------------------------------------------------------------//! receive.void SocketUN::receive(void *buffer, unsigned long Size)    throw (NetworkError,           NetworkSignal){    assert(_est_init_un);    long nReceived = 0 ;#ifndef SOCKUN_BUFFER_LENGTH    long RBLength = 0 ;#endif    pD->Out(pdTrace, "Beginning to receive UN message...");    while (RBLength < Size)        {#ifdef SOCKUN_BUFFER_LENGTH            nReceived = read(_socket_un,                             ReadBuffer + RBLength,                             SOCKUN_BUFFER_LENGTH - RBLength);#else            nReceived = read(_socket_un,                             (char *) buffer + RBLength,                             Size - RBLength);#endif            if (nReceived < 0) {                pD->Out(pdExcept, "Error while receiving on UN socket.");                // Incoming Signal                if (errno == EINTR) {                    if (HandlerType == stSignalInterrupt)                        throw NetworkSignal();                    else                        pD->Out(pdExcept, "RecevoirUN ignoring signal interruption.");                }                // Other errors                else {                    perror("UN Socket(RecevoirUN) : ");                    throw NetworkError("Error while receiving UN message.");                }            }            if (nReceived == 0) {                pD->Out(pdExcept, "UN connection has been closed by peer.");                throw NetworkError("Connection closed by client.");            }            if (nReceived > 0) {                RBLength += nReceived ;                RcvdBytesCount += nReceived ;                pD->Out(pdTrace, "Received %ld bytes out of %ld.", RBLength, Size);            }        }#ifdef SOCKUN_BUFFER_LENGTH    memcpy(buffer, (void *) ReadBuffer, Size);    memmove((void *) ReadBuffer,            (void *)(ReadBuffer + Size),            RBLength - Size);    RBLength -= Size ;#endif}}// $Id: SocketUN.cc,v 3.9 2003/08/20 18:40:02 breholee Exp $

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -