source: trunk/MagicSoft/Control/SubsystemIO/TCPSender.cxx@ 3766

Last change on this file since 3766 was 1054, checked in by casaldaliga, 23 years ago
changed .H to .hxx in includes to work with new naming
File size: 5.7 KB
Line 
1/* Copyright (C) 2001 Marc Casaldaliga Albisu <casaldaliga@ifae.es>
2================================================================
3
4 This code is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This code is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with Emacs (which is required to make this stuff work); if
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.
18==================================================================
19*/
20#include "TCPSender.hxx"
21#include "PeriodicAction.hxx"
22#include "socket_functions.h"
23#include <iostream>
24#include <string.h>
25#include <unistd.h>
26#include <errno.h>
27#include <stdio.h>
28
29TCPSender::TCPSender (char * servName_, unsigned int servPort_ )
30 :retryingTime(3000000),tryingConnect(retryingTime),servPort(servPort_),comMode(false),newReceived(false)//,servName(servName_)
31{
32 strcpy(servName,servName_);
33 //prepare the name
34 init_sockaddr (&server, servName_, servPort);
35 //this->Reset;
36
37
38}
39TCPSender::~TCPSender(){
40 if(comMode){
41 CloseConnection();
42 }
43}
44
45void TCPSender::CloseConnection(){
46 if (comMode){
47#ifdef DEBUG
48 cout<<"TCPSender: closing socket to server "<<servName<<":"<<servPort<<"\n";
49#endif
50 close(socketItself);
51 comMode=false;
52 }
53}
54void TCPSender::Reset() {
55 if (comMode){
56 CloseConnection();
57 }
58 //Tryingconnect PeriodicAction object DO this->isTrialToConnectSuccesful periodically WHILE this call is NOT returning true, that is is retrying until connection is succesfull. All the threading is done inside PeriodicAction!
59 tryingConnect.DoWhileNot(slot(this, &TCPSender::isTrialToConnectSuccesful) );
60
61// // tryingConnect.FinallyDo(... callback to call when tryingConnect is finished, for example Start reporting periodically (start another PeriodicAction
62// // supose we have a virtual method WhenConnectionIsEstablished
63// tryingConnect.FinallyDo(slot(this,&TCPSender::WhenConnectionIsEstablished));
64 tryingConnect.Start();
65
66}
67
68int TCPSender::IODescriptor(){ //returns file descriptor (e.g. to use with IONotifier)
69 return socketItself;
70
71}
72
73bool TCPSender::isTrialToConnectSuccesful(){
74 //create the socketItself. After a failed connect call the socket has to be initialized again (?)
75 socketItself = socket (PF_INET, SOCK_STREAM, 0);
76 if ( (socketItself < 0) || (prepare_socket(socketItself) == -1) ) {
77 perror("TCPSender: socket (client)");
78 exit (EXIT_FAILURE);
79 }
80#ifdef DEBUG
81 printf("TCPSender: trying to connect\n");
82#endif
83 if (0 > connect (socketItself,
84 (struct sockaddr *) &server,
85 sizeof (server))){
86 int myerrno=errno;
87 perror("TCPSender: connect. Retrying");
88 comMode=false;
89 close(socketItself);
90
91 return false;
92
93 }else{
94 comMode=true;
95// fconfigure $socketItself -buffering line
96#ifdef DEBUG
97 printf("TCPSender: TCPSender: successful connection\n");
98#endif
99 return true;
100 }
101}
102
103
104void TCPSender::Send (char *msg ){ //Syncronous send
105 char buffer[MAXMSG];
106
107 strcpy(buffer,msg);
108 unsigned int len=strlen(buffer);
109 buffer[len]='\n';
110 buffer[len+1]='\0';
111#ifdef DEBUG
112 printf("TCPSender: sending %s \n",buffer);
113#endif
114
115 if(write(socketItself, buffer, strlen(buffer)) != strlen(buffer)){
116 int myerrno=errno;
117 }
118// char * eol="\n";
119// if(write(socketItself, eol, strlen(eol)) != strlen(eol)){
120// int myerrno=errno;
121// }
122// // fsync(readoutSend);
123}
124
125
126void TCPSender::Receive () { //Syncronous receive. If you are not sure there will be data to read, schedule this receive with IONotifier or something. Otherwise it will block
127#ifdef DEBUG
128 printf("TCPSender: Receive from TCPSender %d\n", this);
129#endif
130 int nbytes;
131 nbytes = read (socketItself, receivedStream, MAXMSG);
132 if (nbytes < 0){
133 /* Read error. */
134 perror("TCPSender: read");
135// this->CloseConnection();
136 exit (EXIT_FAILURE);
137 }else if (nbytes == 0){
138
139 /* End-of-file. */
140 receivedStream[0]='0';
141 receivedStream[1]='\0';
142 this->CloseConnection();
143 }else{
144 /* Data read. */
145 //look for '\n' and chomp, in anycase read doesn't supply the \n so add it
146 if(receivedStream[nbytes-1]=='\n'){
147 receivedStream[nbytes-1]='\0';
148#ifdef DEBUG
149// printf("TCPSender: %c%c%c chomp\n", receivedStream[nbytes-3],receivedStream[nbytes-2],receivedStream[nbytes-1]);
150
151#endif
152 }else{
153 receivedStream[nbytes]='\0';
154 }
155#ifdef DEBUG
156 printf("TCPSender: got message: `%s'\n", receivedStream);
157#endif
158 this->process();
159 newReceived=true;
160 }
161}
162
163string TCPSender::ReturnNew () {
164 if (newReceived) {
165 newReceived=false;
166 return string(receivedStream);
167 }else{
168 return string("0");
169 }
170}
171
172//this public method should be capitalized for some consistency. Put the change should be propagated. class Make up!
173void TCPSender::process (){
174//to be overriden
175#ifdef DEBUG
176 printf("TCPSender: message Received [%s] and processed from server %s:%d \n",receivedStream,servName,servPort);
177#endif
178}
179
180
181
Note: See TracBrowser for help on using the repository browser.