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); }
Link Copied
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
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
/////////////////////////////////////////////////////////////////////////////// /* 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 ); }
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
For more complete information about compiler optimizations, see our Optimization Notice.