Community
cancel
Showing results for 
Search instead for 
Did you mean: 
krishna_m_
Beginner
453 Views

intel C++ in windows / linux on a socket.c file...

Hi all

in Linux, with ICC (16.0.3 on IA-32) I can compile a socket.c file and hence I can make a .a file 
which contains the following C program (see below for <socket.c>)

But in WINDOWS [7] version of ICL (16.0.3) I couldnt successfully compile it....

(I tried added such as ...

#ifdef WIN32
   #include "winsock.h"
   #include "winsock2.h"
   #include <windows.h>
#else
   #include <sys/socket.h>
   #include <sys/un.h>
#endif

  etc. but no use of it ....)

Here I need an advice - how I can I compile this file in Windows using ICL (intels C) compiler ?

I really need this file to make a porting job  - which port a linux application into Windows. Please also note that
The same file is compiled in GCC of Cygwin in windows without any trouble !

Haopy some can help me

With best regards

Krishna mohan 

 

/* A minimal wrapper for socket communication.

Copyright (C) 2013, Joshua More and Michele Ceriotti
Copyright (C) 2016, Bálint Aradi (adapted to F2003 C-bindings)

...
Functions:
   error: Prints an error message and then exits.
   open_socket_: Opens a socket with the required host server, socket type and
      port number.
   write_buffer_: Writes a string to the socket.
   read_buffer_: Reads data from the socket.
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>

void connect_inet_socket(int *psockfd, const char* host, int port)
/* Opens an internet socket.
   
   Note that fortran passes an extra argument for the string length,
   but this is ignored here for C compatibility.
   
   Args:
   psockfd: The id of the socket that will be created.
   port: The port number for the socket to be created. Low numbers are
         often reserved for important channels, so use of numbers of 4
         or more digits is recommended.
   host: The name of the host server.
*/
  
{
  int sockfd, ai_err;
  
  // creates an internet socket
  
  // fetches information on the host      
  struct addrinfo hints, *res;  
  char service[256];
  
  memset(&hints, 0, sizeof(hints));
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_family = AF_UNSPEC;
  hints.ai_flags = AI_PASSIVE;
  
  sprintf(service, "%d", port); // convert the port number to a string
  ai_err = getaddrinfo(host, service, &hints, &res); 
  if (ai_err!=0) { 
    printf("Error code: %i\n",ai_err);
    perror("Error fetching host data. Wrong host name?");
    exit(-1);
  }
  
  // creates socket
  sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  if (sockfd < 0) { 
    perror("Error opening socket");
    exit(-1);
  }
  
  // makes connection
  if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
    perror("Error opening INET socket: wrong port or server unreachable");
    exit(-1); 
  }
  freeaddrinfo(res);
  
  *psockfd = sockfd;
}

void connect_unix_socket(int *psockfd, const char* pathname)
/* Opens a unix socket.
   
   Note that fortran passes an extra argument for the string length,
   but this is ignored here for C compatibility.
   
   Args:
   psockfd: The id of the socket that will be created.
   pathname: The name of the file to use for sun_path.
*/
  
{
  int sockfd, ai_err;
  
  struct sockaddr_un serv_addr;
  
  printf("Connecting to :%s:\n",pathname);

  // fills up details of the socket addres
  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sun_family = AF_UNIX;
  /* Beware of buffer over runs
     UNIX Network Programming by Richard Stevens mentions
     that the use of sizeof() is ok, but see 
     http://mail-index.netbsd.org/tech-net/2006/10/11/0008.html
  */
  if ((int)strlen(pathname)> sizeof(serv_addr.sun_path)) {
    perror("Error opening UNIX socket: pathname too long\n");
    exit(-1); 
  } else {     
    strcpy(serv_addr.sun_path, pathname);
  }
  // creates a unix socket
  
  // creates the socket
  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  
  // connects
  if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
    perror("Error opening UNIX socket: path unavailable, or already existing");
    exit(-1); 
  }
  *psockfd = sockfd;
}

void writebuffer_socket(int sockfd, const void *data, int len)
/* Writes to a socket.

Args:
   sockfd: The id of the socket that will be written to.
   data: The data to be written to the socket.
   len: The length of the data in bytes.
*/
{
   int n;

   n = write(sockfd, (char *) data, len);
   if (n < 0) { 
     perror("Error writing to socket: server has quit or connection broke");
     exit(-1);
   }
}


void readbuffer_socket(int sockfd, void *data, int len)
/* Reads from a socket.

Args:
   sockfd: The id of the socket that will be read from.
   data: The storage array for data read from the socket.
   len: The length of the data in bytes.
*/

{
   int n, nr;
   char *pdata;

   pdata = (char *) data;
   n = nr = read(sockfd, pdata, len);

   while (nr > 0 && n < len) { 
     nr = read(sockfd, &(pdata), len - n);
     n += nr;
   }
   if (n == 0) {
     perror("Error reading from socket: server has quit or connection broke");
     exit(-1);
   }
}


void shutdown_socket(int sockfd)
/* Shuts down the socket.
*/
{
  shutdown(sockfd, 2);
  close(sockfd);
}

 

0 Kudos
6 Replies
Varsha_M_Intel
Employee
453 Views

Hi ,

What is the error you are getting? What version of Visual Studio are you using? Could you provide the options to compile your program?

Thanks,
Varsha

 

krishna_m_
Beginner
453 Views

Hi 

thanks for the reply.

I use Ifort 2016.3.207, Windows 7, and Cygwin GCC 4.6.3. Currently I am not using MSVS.
Please note that I use Cygwin to run the make etc.

As I said, I am trying to port a software for windows which use socket.c and fsockets.f90 in linux (and in Linux I can GCC for socket.c without any trouble... )

Pleas see the attachment for fsocket.f90 in below portion.

I noted :

(1) In Linux I can see NO Leading or trailing underscore, but in windows gcc produce leading underscore:

(2) In Windows, A completely inverted Uppercase letters is included in .o fortran file 
(eg. _F90SOCKETS_mp_CONNECT_INET_SOCKET instead of f90sockets_MP_connect_unix_socket_ ) and its underscore 
is Leading not trailing.


------------------------------------------------------
with $ nm libfsockets.a (which is produced by: ar rcs libfsockets.a sockets.o fsockets.o ),

IN LINUX

sockets.o:            
         U close            
         U connect            
00000000 T connect_inet_socket            
00000140 T connect_unix_socket            
         U exit            
         U freeaddrinfo            

...


fsockets.o:                
         U connect_inet_socket                
         U connect_unix_socket                
00000000 T f90sockets._                
00000010 T f90sockets_MP_connect_inet_socket_                
000000e0 T f90sockets_MP_connect_unix_socket_                
000005c0 T f90sockets_MP_readbuffer_d_                


______________________________________________________


in Windows (ifort (fsockets.o) GCC(sockets.c) version)

sockets.o:

         U _close
         U _connect
00000000 T _connect_inet_socket
00000141 T _connect_unix_socket
         U _exit

.....

         U _connect_inet_socket
         U _connect_unix_socket
00000000 T _F90SOCKETS.
00000010 T _F90SOCKETS_mp_CONNECT_INET_SOCKET
000000e0 T _F90SOCKETS_mp_CONNECT_UNIX_SOCKET
000005d0 T _F90SOCKETS_mp_READBUFFER_D
000006f0 T _F90SOCKETS_mp_READBUFFER_DV


------------------------------------------------------

(3) Using cygwins GCC/gfortran I could compile these ...

My options are:

# Options for the Fortran compiler

FXXOPT = -O2 -qopenmp -openmp /Qopenmp -ip -standard-semantics -xW -fpp  (for ifort)
CCOPT  = -O2 -ip                                                          (for gcc  )

Hope you can make some suggestions - at least how to adjust trailing/leading underscores and to convert _F90SOCKETS_mp_CONNECT_UNIX_SOCKET (etc ) to f90sockets_MP_connect_unix_socket_ which may solve the issue I guess...

Krishna mohan G P

! f90sockets.f90 is following .............................................................

module f90sockets
  use iso_c_binding
  implicit none
  private

  public :: connect_inet_socket, connect_unix_socket, readbuffer, writebuffer, shutdown_socket


  interface writebuffer
    module procedure writebuffer_s, writebuffer_d, writebuffer_dv, writebuffer_i
  end interface writebuffer

  interface readbuffer
    module procedure readbuffer_s
    module procedure readbuffer_dv
    module procedure readbuffer_d
    module procedure readbuffer_i
  end interface readbuffer


  ! interface bindings for c routines
  interface

    subroutine connect_inet_socket_c(sockfd, host, port) bind(C, name='connect_inet_socket')
      import :: c_int, c_char
      integer(c_int), intent(out) :: sockfd
      character(kind=c_char), dimension(*), intent(in) :: host
      integer(c_int), value, intent(in) :: port
    end subroutine connect_inet_socket_c

    subroutine connect_unix_socket_c(sockfd, host) bind(C, name='connect_unix_socket')
      import :: c_int, c_char
      integer(c_int), intent(out) :: sockfd
      character(kind=c_char), dimension(*), intent(in) :: host
    end subroutine connect_unix_socket_c

    subroutine writebuffer_socket_c(sockfd, data, len) bind(C, name='writebuffer_socket')
      import :: c_int, c_ptr
      integer(c_int), value, intent(in) :: sockfd
      type(c_ptr), value, intent(in) :: data
      integer(c_int), value :: len
    end subroutine writebuffer_socket_c

    subroutine readbuffer_socket_c(sockfd, data, len) bind(C, name='readbuffer_socket')
      import :: c_int, c_ptr
      integer(c_int), value, intent(in) :: sockfd
      type(c_ptr), value, intent(in) :: data
      integer(c_int), value, intent(in) :: len
    end subroutine readbuffer_socket_c

    subroutine shutdown_socket_c(sockfd) bind(C, name='shutdown_socket')
      import :: c_int
      integer(c_int), value, intent(in) :: sockfd
    end subroutine shutdown_socket_c

  end interface

contains

  ! Internet socket
  subroutine connect_inet_socket(sockfd, host, port)
    integer(c_int), intent(out) :: sockfd
    character(kind=c_char, len=*), intent(in) :: host
    integer(c_int), intent(in) :: port

    call connect_inet_socket_c(sockfd, trim(host) // c_null_char, port)

  end subroutine connect_inet_socket


  ! Unix socket
  subroutine connect_unix_socket(sockfd, host)
    integer(c_int), intent(out) :: sockfd
    character(kind=c_char, len=*), intent(in) :: host

    call connect_unix_socket_c(sockfd, trim(host) // c_null_char)

  end subroutine connect_unix_socket


  ! Close the socket
  subroutine shutdown_socket(sockfd)
    integer(c_int), intent(in) :: sockfd

    call shutdown_socket_c(sockfd)

  end subroutine shutdown_socket


  ! write a float (real)
  subroutine writebuffer_d(sockfd, fdata)
    integer(c_int), intent(in) :: sockfd
    real(c_double), target, intent(in) :: fdata

    call writebuffer_socket_c(sockfd, c_loc(fdata), 8_c_int)

  end subroutine writebuffer_d


  ! Write an integer
  subroutine writebuffer_i(sockfd, fdata)
    integer(c_int), intent(in) :: sockfd
    integer(c_int), target, intent(in) :: fdata

    call writebuffer_socket_c(sockfd, c_loc(fdata), 4_c_int)

  end subroutine writebuffer_i


  ! write a string
  subroutine writebuffer_s(sockfd, fstring)
    integer(c_int), intent(in) :: sockfd
    character(kind=c_char, len=*), intent(in) :: fstring

    character(kind=c_char), target :: cstring(len(fstring))
    integer :: trimlen

    cstring(:) = transfer(fstring, cstring)
    trimlen = len_trim(fstring)
    cstring(trimlen + 1:) = ' '
    call writebuffer_socket_c(sockfd, c_loc(cstring), size(cstring, kind=c_int))

  end subroutine writebuffer_s


  subroutine writebuffer_dv(sockfd, fdata)
    integer(c_int), intent(in) :: sockfd
    real(c_double), target, intent(in) :: fdata(:)

    call writebuffer_socket_c(sockfd, c_loc(fdata), 8_c_int * size(fdata, kind=c_int))

  end subroutine writebuffer_dv


  subroutine readbuffer_d(sockfd, fdata)
    integer(c_int), intent(in) :: sockfd
    real(c_double), target, intent(out) :: fdata

    call readbuffer_socket_c(sockfd, c_loc(fdata), 8_c_int)

  end subroutine readbuffer_d


  subroutine readbuffer_i(sockfd, fdata)
    integer(c_int), intent(in) :: sockfd
    integer(c_int), target, intent(out) :: fdata

    call readbuffer_socket_c(sockfd, c_loc(fdata), 4_c_int)

  end subroutine readbuffer_i


  subroutine readbuffer_s(sockfd, fstring)
    integer(c_int), intent(in) :: sockfd
    character(kind=c_char, len=*), intent(out) :: fstring

    character(kind=c_char), target :: cstring(len(fstring))
    integer :: ii

    call readbuffer_socket_c(sockfd, c_loc(cstring), size(cstring, kind=c_int))
    fstring = ""
    do ii = 1, size(cstring)
      if (cstring(ii) == c_null_char) then
        exit
      end if
      fstring(ii:ii) = cstring(ii)
    end do

  end subroutine readbuffer_s


  subroutine readbuffer_dv(sockfd, fdata)
    integer(c_int), intent(in) :: sockfd
    real(c_double), target, intent(out) :: fdata(:)

    call readbuffer_socket_c(sockfd, c_loc(fdata), 8_c_int * size(fdata, kind=c_int))

  end subroutine readbuffer_dv

end module f90sockets

 

SKost
Valued Contributor II
453 Views

Krishna, I'll do a very short follow up on your Post #1: 1. There are no any problems with Intel C++ compiler 2. You need to re-implement, or port, a function with connect functionality 3. If you really want to get as better as possible experience I recommend you look for POSIX Man Pages for UNIX/LINUX OSs, and MSDN for Windows OSs 4. In case of Windows any version of Microsoft Platform SDK has lots of examples on how sockets should be used in Windows OSs 5. An example on how you should do it will be posted. Once again, this is not a problem with Intel C++ compiler and you need to do the job if this is your job or student assignment.
SKost
Valued Contributor II
453 Views

///////////////////////////////////////////////////////////////////////////////
/* A minimal wrapper for socket communication.

Copyright (C) 2013, Joshua More and Michele Ceriotti
Copyright (C) 2016, Bálint Aradi (adapted to F2003 C-bindings)

Functions:
   error: Prints an error message and then exits.
   open_socket_: Opens a socket with the required host server, socket type and
      port number.
   write_buffer_: Writes a string to the socket.
   read_buffer_: Reads data from the socket.

- 02.02.2017: Sergey Kostrov's ( SK ) notes:

 - https://software.intel.com/en-us/forums/intel-c-compiler/topic/710141
 - For compilation with Intel C++ compiler for Windows without linking use
   icl.exe -c <filename>
*/

///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>

///////////////////////////////////////////////////////////////////////////////
// SK

#ifdef _WIN32
 #include <winsock2.h>
 #include <ws2tcpip.h>
#else
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <sys/un.h>
 #include <netdb.h>
#endif

///////////////////////////////////////////////////////////////////////////////
// SK

void connect_inet_socket( int *psockfd, const char* host, int port );

#ifdef _WIN32
void connect_windows_socket( int *psockfd, const char* pathname );
#else
void connect_unix_socket( int *psockfd, const char* pathname );
#endif

void writebuffer_socket( int sockfd, const void *data, int len );
void readbuffer_socket( int sockfd, void *data, int len );
void shutdown_socket( int sockfd );

///////////////////////////////////////////////////////////////////////////////
// SK
/* Access to sockets needs to be done with a wrapper function 'connect_socket'
   and it is substituted by 'connect_windows_socket' or by 'connect_unix_socket'
   ( depends on a state of the macro _WIN32 ) during preprocessing phase of
   the compilation.
   For portability 'connect_windows_socket' and 'connect_unix_socket' shouldn't
   be used directly and the wrapper function 'connect_socket' must be used instead.
*/

#ifdef _WIN32
 #define connect_socket   connect_windows_socket
#else
 #define connect_socket   connect_unix_socket
#endif

///////////////////////////////////////////////////////////////////////////////
/* Opens an internet socket.
   
   Note that fortran passes an extra argument for the string length,
   but this is ignored here for C compatibility.
   
   Args:
   psockfd: The id of the socket that will be created.
   port: The port number for the socket to be created. Low numbers are
         often reserved for important channels, so use of numbers of 4
         or more digits is recommended.
   host: The name of the host server.
*/

void connect_inet_socket( int *psockfd, const char* host, int port )
{
  int sockfd, ai_err;
  
  // creates an internet socket
  
  // fetches information on the host      
  struct addrinfo hints, *res;  
  char service[256];
  
  memset(&hints, 0, sizeof(hints));
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_family = AF_UNSPEC;
  hints.ai_flags = AI_PASSIVE;
  
  sprintf(service, "%d", port); // convert the port number to a string
  ai_err = getaddrinfo(host, service, &hints, &res); 
  if (ai_err!=0) { 
    printf("Error code: %i\n",ai_err);
    perror("Error fetching host data. Wrong host name?");
    exit(-1);
  }
  
  // creates socket
  sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  if (sockfd < 0) { 
    perror("Error opening socket");
    exit(-1);
  }
  
  // makes connection
  if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
    perror("Error opening INET socket: wrong port or server unreachable");
    exit(-1); 
  }
  freeaddrinfo(res);
  
  *psockfd = sockfd;
}

///////////////////////////////////////////////////////////////////////////////
// SK
/* Opens a socket.
   
   Note that fortran passes an extra argument for the string length,
   but this is ignored here for C compatibility.
   
   Args:
   psockfd: The id of the socket that will be created.
   pathname: The name of the file to use for sun_path.
*/

#ifdef _WIN32

void connect_windows_socket( int *psockfd, const char* pathname )
{
  // Required functionality for Windows

  // ...
}

#else

void connect_unix_socket( int *psockfd, const char* pathname )
{
  // Required functionality for Unix

  int sockfd, ai_err;
  
  struct sockaddr_in serv_addr;
  
  printf("Connecting to :%s:\n",pathname);

  // fills up details of the socket addres
  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sun_family = AF_UNIX;
  /* Beware of buffer over runs
     UNIX Network Programming by Richard Stevens mentions
     that the use of sizeof() is ok, but see 
  http://mail-index.netbsd.org/tech-net/2006/10/11/0008.html
  */
  if ((int)strlen(pathname)> sizeof(serv_addr.sun_path)) {
    perror("Error opening UNIX socket: pathname too long\n");
    exit(-1); 
  } else {     
    strcpy(serv_addr.sun_path, pathname);
  }
  // creates a unix socket
  
  // creates the socket
  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  
  // connects
  if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
    perror("Error opening UNIX socket: path unavailable, or already existing");
    exit(-1); 
  }
  *psockfd = sockfd;
}

#endif

///////////////////////////////////////////////////////////////////////////////
/* Writes to a socket.

Args:
   sockfd: The id of the socket that will be written to.
   data: The data to be written to the socket.
   len: The length of the data in bytes.
*/

void writebuffer_socket( int sockfd, const void *data, int len )
{
   int n;

   n = write(sockfd, (char *) data, len);
   if (n < 0) { 
     perror("Error writing to socket: server has quit or connection broke");
     exit(-1);
   }
}

///////////////////////////////////////////////////////////////////////////////
/* Reads from a socket.

Args:
   sockfd: The id of the socket that will be read from.
   data: The storage array for data read from the socket.
   len: The length of the data in bytes.
*/

void readbuffer_socket( int sockfd, void *data, int len )
{
   int n, nr;
   char *pdata;

   pdata = (char *) data;
   n = nr = read(sockfd, pdata, len);

   while (nr > 0 && n < len) { 
     nr = read(sockfd, &(pdata), len - n);
     n += nr;
   }
   if (n == 0) {
     perror("Error reading from socket: server has quit or connection broke");
     exit(-1);
   }
}

///////////////////////////////////////////////////////////////////////////////
/* Shuts down the socket.
*/

void shutdown_socket( int sockfd )
{
  shutdown( sockfd, 2 );
  close( sockfd );
}

 

SKost
Valued Contributor II
453 Views

Source file attached as well.
krishna_m_
Beginner
453 Views

dear Sergey,

Many thanks for the infos (actually it was not a job/assignment work, it is a voluntary  source  contribution to a publicly available science package...)

I have ran your files and I think need to edit the F90 file for the windows. I will let you know the progress

cheers

krishna