ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Socket Programming in ROS

asked 2013-03-05 07:29:08 -0600

Ali Asad gravatar image

updated 2013-03-05 07:41:38 -0600

SL Remy gravatar image

Hi all,

I wanted to ask a simple question. I was trying to establish TCP/IP server in ROS node. Well my concept was really simple to make ROS node that will work as a server , and then I will use that server to send the values(velocities and joint values) in a string.

my code is fairly simple,

#include <iostream>     
#include <cstdlib>      
#include <unistd.h>     
#include <cerrno>       
#include <cstring>  
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <csignal>  

#include "ros/ros.h"
#include "nav_msgs/Odometry.h"

using namespace std;
#define PORTNUMBER 8001    // port number of connection
#define BACKLOG 2     // max number of client
#define MAXDATASIZE 100 // maximum accepted datasize at a time 



nav_msgs::Odometry lastReceivedOdometry;


//need to handle zombi processes by sigaction()
void sigchld_handler(int s)
{
        while(wait(NULL) > 0);
}

int main(int argc, char **argv)
{

  ros::init(argc, argv, "socket");

  ros::NodeHandle n;

  ros::spin();

  int sockfd, new_fd, mySelect, sockoptset, bindit, listento, actionsig, numbytes,sended;  
  char buf[MAXDATASIZE];
  struct sockaddr_in my_addr;           // my address information
  struct sockaddr_in their_addr;        // address information of connected machine
  int sin_size;
  struct sigaction sa;          // need to handle "zombi" processes after ended child processes which are created by fork()
  int yes=1;                // needed by setsockopt()

  fd_set read_fd;
  struct timeval timeout;
  timeout.tv_sec = 15;
  timeout.tv_usec = 0;

  // create the socket
  sockfd = socket(AF_INET, SOCK_STREAM, 0); 
  // error check for socket()
  if (sockfd == -1) {
        cout <<"error socket"<< strerror(errno);
        exit(1);
  }

  my_addr.sin_family = AF_INET;         // host byte order , AF_INET = IPv4 Internet Protocols for Linux
  my_addr.sin_port = htons(PORTNUMBER);     // sin_port is in short-network byte order,htons()=converts PORTNUMBER to network byte order
  my_addr.sin_addr.s_addr = INADDR_ANY; // use my address automatically, use "INADDR_ANY"(0 so no need htons) or "inet_addr("192.120.13.1")
  memset(&(my_addr.sin_zero), '\0', 8); // make the rest of the structure zero

  //assign the address specified to the socket 
  bindit = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
  //error check for bind()
  if (bindit == -1) {
        cout <<"error bindit"<< strerror(errno);
            exit(1);
  }

  //listen the connection on created socket
  listento = listen(sockfd, BACKLOG);
  //error check for listen()
  if (listento == -1) {
       cout <<"error listento"<< strerror(errno);
            exit(1);
  }

  //examine and change the "zombi" processes signal actions
  sa.sa_handler = sigchld_handler;  // reap all dead processes
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_RESTART;
  actionsig = sigaction(SIGCHLD, &sa, NULL);
  //error check for sigaction()
  if (actionsig == -1) {
       cout <<"error actionsig"<< strerror(errno);
            exit(1);
  }
  sin_size = sizeof(struct sockaddr_in);

  // accept a connection on listened socket
  new_fd = accept(sockfd, (struct sockaddr *)&their_addr, (socklen_t*)&sin_size);
  //error check for accept()
  if (new_fd == -1) {           
         cout << strerror(errno) << "accept() has failed!" << endl ;
  }

  cout << "server: got connection from " << inet_ntoa(their_addr.sin_addr) << endl; 


  FD_ZERO(&read_fd);
  FD_SET(new_fd,&read_fd);
  mySelect = select(new_fd+1,&read_fd,NULL,NULL,&timeout);
  if(mySelect == 1 && (FD_ISSET(new_fd,&read_fd))){
            while(new_fd !=-1){
                numbytes=recv(new_fd, buf, MAXDATASIZE-1, 0);
                if(numbytes == 0){
                    cout << "Connection has terminated by " << inet_ntoa(their_addr.sin_addr)<<endl;
                    close(new_fd);
                    close(sockfd);
                    return 0;
                }
                buf[numbytes] = '\0';
                cout << numbytes << endl;
                if(strcmp ...
(more)
edit retag flag offensive close merge delete

Comments

2

Can you describe what happens when you run your code? What do you mean by "doesn't work"?

SL Remy gravatar image SL Remy  ( 2013-03-05 07:31:34 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted
5

answered 2013-03-05 08:13:30 -0600

dornhege gravatar image

updated 2013-03-05 08:17:22 -0600

You're calling ros::spin() first, which blocks, so you code isn't run.

The rest of your code doesn't seem ROS related, so if that doesn't work, you should seek out other sources.

edit flag offensive delete link more
0

answered 2015-10-12 01:08:51 -0600

Check this one.....Socket Programming basics

Chris

edit flag offensive delete link more
-2

answered 2013-03-05 09:44:18 -0600

Ali Asad gravatar image

thank I got it after posting the code , its working now thnaks

edit flag offensive delete link more

Comments

What is different, what change did you make that allows your code to now work?

SL Remy gravatar image SL Remy  ( 2013-03-06 02:07:26 -0600 )edit

Hey Ali, Could you please share it, how you resolve this problem ?

Max gravatar image Max  ( 2013-09-05 07:10:47 -0600 )edit

Question Tools

Stats

Asked: 2013-03-05 07:29:08 -0600

Seen: 5,450 times

Last updated: Oct 12 '15