ffead.server.doc
Client.cpp
1 /*
2  Copyright 2010, Sumeet Chhetri
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16 /*
17  * Client.cpp
18  *
19  * Created on: Mar 27, 2010
20  * Author: sumeet
21  */
22 
23 #include "Client.h"
24 
25 Client::Client() {
26  logger = Logger::getLogger("Client");
27  connected = false;
28 }
29 
30 Client::~Client() {
31  closeConnection();
32 }
33 
34 bool Client::connection(string host,int port)
35 {
36  if(host=="localhost")
37  {
38  return connectionUnresolv(host, port);
39  }
40 
41  struct sockaddr_in *remote;
42  int tmpres;
43  char *ip;
44 
45  sockfd = create_tcp_socket();
46  ip = get_ip((char*)host.c_str());
47  fprintf(stderr, "IP is %s\n", ip);
48  remote = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *));
49  remote->sin_family = AF_INET;
50  tmpres = inet_pton(AF_INET, ip, (void *)(&(remote->sin_addr.s_addr)));
51  if( tmpres < 0)
52  {
53  perror("Can't set remote->sin_addr.s_addr");
54  return false;
55  }
56  else if(tmpres == 0)
57  {
58  fprintf(stderr, "%s is not a valid IP address\n", ip);
59  return false;
60  }
61  remote->sin_port = htons(port);
62 
63  if(connect(sockfd, (struct sockaddr *)remote, sizeof(struct sockaddr)) < 0){
64  perror("Could not connect");
65  connected = false;
66  } else {
67  connected = true;
68  }
69  free(remote);
70  free(ip);
71 
72  return connected;
73 }
74 
75 
76 bool Client::connectionUnresolv(string host,int port)
77 {
78  struct addrinfo hints, *servinfo, *p;
79  int rv;
80  char s[INET6_ADDRSTRLEN];
81 
82  memset(&hints, 0, sizeof hints);
83  hints.ai_family = AF_UNSPEC;
84  hints.ai_socktype = SOCK_STREAM;
85  string sport = CastUtil::lexical_cast<string>(port);
86  if ((rv = getaddrinfo(host.c_str(), sport.c_str(), &hints, &servinfo)) != 0) {
87  fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
88  return false;
89  }
90 
91  // loop through all the results and connect to the first we can
92  for(p = servinfo; p != NULL; p = p->ai_next) {
93  if ((sockfd = socket(p->ai_family, p->ai_socktype,
94  p->ai_protocol)) == -1) {
95  perror("client: socket");
96  continue;
97  }
98 
99  if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
100  close(sockfd);
101  perror("client: connect");
102  connected = false;
103  continue;
104  } else {
105  connected = true;
106  }
107  break;
108  }
109 
110  if (p == NULL) {
111  connected = false;
112  fprintf(stderr, "client: failed to connect\n");
113  return false;
114  }
115 
116  inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
117  s, sizeof s);
118  //printf("client: connecting to %s\n", s);
119 
120  freeaddrinfo(servinfo); // all done with this structure
121 
122  return connected;
123 }
124 
125 void Client::setSocketBlocking()
126 {
127  fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0) | O_NONBLOCK);
128 }
129 
130 void Client::setSocketNonBlocking()
131 {
132  fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0) | O_SYNC);
133 }
134 
135 int Client::sendData(string data)
136 {
137  int sent = 0;
138  while(data.length()>0)
139  {
140  int tmpres = send(sockfd, data.c_str(), data.length(), 0);
141  if(tmpres == -1){
142  perror("Can't send data");
143  }
144  data = data.substr(tmpres);
145  }
146  return sent;
147 }
148 
149 string Client::getTextData(string hdrdelm,string cntlnhdr)
150 {
151  int er=-1;
152  bool flag = true;
153  string alldat;
154  int cntlen;
155  char buf[MAXBUFLE];
156  BIO* sbio=BIO_new_socket(sockfd,BIO_NOCLOSE);
157  BIO* io=BIO_new(BIO_f_buffer());
158  BIO_push(io,sbio);
159  while(flag)
160  {
161  er = BIO_gets(io,buf,MAXBUFLE-1);
162  if(er==0)
163  {
164  if(io!=NULL)BIO_free_all(io);
165  //logger << "\nsocket closed before being serviced" <<flush;
166  return alldat;
167  }
168  if(!strcmp(buf,hdrdelm.c_str()))
169  {
170  string tt(buf, er);
171  alldat += tt;
172  break;
173  }
174  string temp(buf, er);
175  temp = temp.substr(0,temp.length()-1);
176  alldat += (temp + "\n");
177  if(temp.find(cntlnhdr)!=string::npos)
178  {
179  std::string cntle = temp.substr(temp.find(": ")+2);
180  cntle = cntle.substr(0,cntle.length()-1);
181  try
182  {
183  cntlen = CastUtil::lexical_cast<int>(cntle);
184  }
185  catch(...)
186  {
187  logger << "bad lexical cast" <<endl;
188  }
189  }
190  memset(&buf[0], 0, sizeof(buf));
191  }
192  while(cntlen>0)
193  {
194  //logger << "reading conetnt " << cntlen;
195  int toRead = cntlen;
196  if(cntlen>MAXBUFLE)
197  toRead = MAXBUFLE - 1;
198  er = BIO_read(io,buf,toRead);
199  if(er==0)
200  {
201  if(io!=NULL)BIO_free_all(io);
202  //logger << "\nsocket closed before being serviced" <<flush;
203  return alldat;
204  }
205  string temp(buf, er);
206  alldat += temp;
207  cntlen -= er;
208  memset(&buf[0], 0, sizeof(buf));
209  }
210  return alldat;
211 }
212 
213 int Client::receive(string& buf,int flag)
214 {
215  char buff[MAXBUFLE+1];
216  memset(buff, 0, sizeof(buff));
217  int t = recv(sockfd, buff, MAXBUFLE, flag);
218  buf = buff;
219  memset(buff, 0, sizeof(buff));
220  return t;
221 }
222 
223 int Client::receivelen(string& buf,int len, int flag)
224 {
225  char buff[len+1];
226  memset(buff, 0, sizeof(buff));
227  int t = recv(sockfd, buff, len, flag);
228  buf = buff;
229  memset(buff, 0, sizeof(buff));
230  return t;
231 }
232 
233 int Client::sendlen(string buf,int len)
234 {
235  return send(sockfd, buf.c_str(), len, 0);
236 }
237 
238 string Client::getBinaryData(int len, bool isLengthIncluded)
239 {
240  //logger << len;
241  string alldat;
242  char *buf1 = new char[len+1];
243  memset(buf1, 0, len);
244  recv(sockfd, buf1, len, 0);
245  for (int var = 0; var < len; ++var) {
246  alldat.push_back(buf1[var]);
247  }
248  memset(buf1, 0, len);
249 
250  int leng = getLengthCl(alldat, len);
251  if(isLengthIncluded)
252  {
253  leng -= len;
254  }
255  //logger << "done reading header length " << leng;
256  char *buf = new char[leng+1];
257  memset(buf, 0, sizeof(buf));
258  recv(sockfd, buf, leng, 0);
259  for (int var = 0; var < leng; ++var) {
260  alldat.push_back(buf[var]);
261  }
262  memset(buf, 0, sizeof(buf));
263  //logger << alldat.length();
264  return alldat;
265 }
266 
267 void Client::closeConnection()
268 {
269  connected = false;
270  close(sockfd);
271 }
272 
273 bool Client::isConnected()
274 {
275  return connected && ClientInterface::isConnected(sockfd);
276 }
277 
278 string Client::getData()
279 {
280  int numbytes;
281  char buf[MAXBUFLE];
282  while ((numbytes = recv(sockfd, buf, MAXBUFLE-1, 0)) == -1)
283  {
284  //perror("recv");
285  if(errno!=EAGAIN)
286  return "";
287  //exit(1);
288  }
289  if(numbytes==0)
290  {
291  connected = false;
292  close(sockfd);
293  return "";
294  }
295  string data(buf,buf+numbytes);
296  memset(&buf[0], 0, sizeof(buf));
297  return data;
298 }