Purpose: Encapsulates a socket
Called by: FGOutput, et. al.
- ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
+ ------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
This program 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
HISTORY
--------------------------------------------------------------------------------
11/08/99 JSB Created
+11/08/07 HDW Added Generic Socket Send
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#include <iostream>
+#include <iomanip>
+#include <cstring>
+#include <cstdio>
#include "FGfdmSocket.h"
+#include "string_utilities.h"
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::string;
namespace JSBSim {
-static const char *IdSrc = "$Id$";
+static const char *IdSrc = "$Id: FGfdmSocket.cpp,v 1.27 2010/05/13 03:07:59 jberndt Exp $";
static const char *IdHdr = ID_FDMSOCKET;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGfdmSocket::FGfdmSocket(string address, int port)
+FGfdmSocket::FGfdmSocket(const string& address, int port, int protocol)
+{
+ sckt = sckt_in = 0;
+ connected = false;
+
+ #if defined(_MSC_VER) || defined(__MINGW32__)
+ WSADATA wsaData;
+ int wsaReturnCode;
+ wsaReturnCode = WSAStartup(MAKEWORD(1,1), &wsaData);
+ if (wsaReturnCode == 0) cout << "Winsock DLL loaded ..." << endl;
+ else cout << "Winsock DLL not initialized ..." << endl;
+ #endif
+
+ if (!is_number(address)) {
+ if ((host = gethostbyname(address.c_str())) == NULL) {
+ cout << "Could not get host net address by name..." << endl;
+ }
+ } else {
+ unsigned int ip;
+ ip = inet_addr(address.c_str());
+ if ((host = gethostbyaddr((char*)&ip, address.size(), PF_INET)) == NULL) {
+ cout << "Could not get host net address by number..." << endl;
+ }
+ }
+
+ if (host != NULL) {
+ if (protocol == ptUDP) { //use udp protocol
+ sckt = socket(AF_INET, SOCK_DGRAM, 0);
+ cout << "Creating UDP socket on port " << port << endl;
+ }
+ else { //use tcp protocol
+ sckt = socket(AF_INET, SOCK_STREAM, 0);
+ cout << "Creating TCP socket on port " << port << endl;
+ }
+
+ if (sckt >= 0) { // successful
+ memset(&scktName, 0, sizeof(struct sockaddr_in));
+ scktName.sin_family = AF_INET;
+ scktName.sin_port = htons(port);
+ memcpy(&scktName.sin_addr, host->h_addr_list[0], host->h_length);
+ int len = sizeof(struct sockaddr_in);
+ if (connect(sckt, (struct sockaddr*)&scktName, len) == 0) { // successful
+ cout << "Successfully connected to socket for output ..." << endl;
+ connected = true;
+ } else { // unsuccessful
+ cout << "Could not connect to socket for output ..." << endl;
+ }
+ } else { // unsuccessful
+ cout << "Could not create socket for FDM output, error = " << errno << endl;
+ }
+ }
+ Debug(0);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGfdmSocket::FGfdmSocket(const string& address, int port)
{
- sckt = sckt_in = size = 0;
+ sckt = sckt_in = 0;
connected = false;
- #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
+ #if defined(_MSC_VER) || defined(__MINGW32__)
WSADATA wsaData;
int wsaReturnCode;
wsaReturnCode = WSAStartup(MAKEWORD(1,1), &wsaData);
else cout << "Winsock DLL not initialized ..." << endl;
#endif
- if (address.find_first_not_of("0123456789.",0) != address.npos) {
+ cout << "... Socket Configuration Sanity Check ..." << endl;
+ cout << "Host name... " << address << ", Port... " << port << "." << endl;
+ cout << "Host name... (char) " << address.c_str() << "." << endl;
+
+ if (!is_number(address)) {
if ((host = gethostbyname(address.c_str())) == NULL) {
cout << "Could not get host net address by name..." << endl;
}
FGfdmSocket::FGfdmSocket(int port)
{
- size = 0;
connected = false;
unsigned long NoBlock = true;
- #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
+ #if defined(_MSC_VER) || defined(__MINGW32__)
WSADATA wsaData;
int wsaReturnCode;
wsaReturnCode = WSAStartup(MAKEWORD(1,1), &wsaData);
if (bind(sckt, (struct sockaddr*)&scktName, len) == 0) { // successful
cout << "Successfully bound to socket for input on port " << port << endl;
if (listen(sckt, 5) >= 0) { // successful listen()
- #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
+ #if defined(_MSC_VER) || defined(__MINGW32__)
ioctlsocket(sckt, FIONBIO, &NoBlock);
sckt_in = accept(sckt, (struct sockaddr*)&scktName, &len);
#else
FGfdmSocket::~FGfdmSocket()
{
- #ifndef macintosh
if (sckt) shutdown(sckt,2);
if (sckt_in) shutdown(sckt_in,2);
- #endif
-
- #ifdef __BORLANDC__
- WSACleanup();
- #endif
Debug(1);
}
char buf[1024];
int len = sizeof(struct sockaddr_in);
int num_chars=0;
- int total_chars = 0;
unsigned long NoBlock = true;
- string data = ""; // todo: should allocate this with a standard size as a
+ string data; // todo: should allocate this with a standard size as a
// class attribute and pass as a reference?
if (sckt_in <= 0) {
- #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
+ #if defined(_MSC_VER) || defined(__MINGW32__)
sckt_in = accept(sckt, (struct sockaddr*)&scktName, &len);
#else
sckt_in = accept(sckt, (struct sockaddr*)&scktName, (socklen_t*)&len);
#endif
if (sckt_in > 0) {
- #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
+ #if defined(_MSC_VER) || defined(__MINGW32__)
ioctlsocket(sckt_in, FIONBIO,&NoBlock);
#else
ioctl(sckt_in, FIONBIO, &NoBlock);
}
if (sckt_in > 0) {
- while ((num_chars = recv(sckt_in, buf, 1024, 0)) > 0) {
- data += string(buf).substr(0,num_chars);
- total_chars += num_chars;
+ while ((num_chars = recv(sckt_in, buf, sizeof buf, 0)) > 0) {
+ data.append(buf, num_chars);
}
#if defined(_MSC_VER)
#endif
}
- return data.substr(0, total_chars);
+ return data;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-int FGfdmSocket::Reply(string text)
+int FGfdmSocket::Reply(const string& text)
{
int num_chars_sent=0;
void FGfdmSocket::Clear(void)
{
- buffer = "";
- size = 0;
+ buffer.str(string());
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGfdmSocket::Clear(string s)
+void FGfdmSocket::Clear(const string& s)
{
- buffer = s + " ";
- size = buffer.size();
+ Clear();
+ buffer << s << ' ';
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGfdmSocket::Append(const char* item)
{
- if (size == 0) buffer += string(item);
- else buffer += string(",") + string(item);
- size++;
+ if (buffer.tellp() > 0) buffer << ',';
+ buffer << item;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGfdmSocket::Append(double item)
{
- char s[25];
-
- sprintf(s,"%12.7f",item);
-
- if (size == 0) buffer += string(s);
- else buffer += string(",") + string(s);
- size++;
+ if (buffer.tellp() > 0) buffer << ',';
+ buffer << std::setw(12) << std::setprecision(7) << item;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGfdmSocket::Append(long item)
{
- char s[25];
+ if (buffer.tellp() > 0) buffer << ',';
+ buffer << std::setw(12) << item;
+}
- sprintf(s,"%12ld",item);
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- if (size == 0) buffer += string(s);
- else buffer += string(",") + string(s);
- size++;
+void FGfdmSocket::Send(void)
+{
+ buffer << '\n';
+ string str = buffer.str();
+ if ((send(sckt,str.c_str(),str.size(),0)) <= 0) {
+ perror("send");
+ }
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGfdmSocket::Send(void)
+void FGfdmSocket::Send(const char *data, int length)
{
- buffer += string("\n");
- if ((send(sckt,buffer.c_str(),buffer.size(),0)) <= 0) {
+ if ((send(sckt,data,length,0)) <= 0) {
perror("send");
- } else {
}
}