git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@12769 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
147
tools/i-pi/drivers/sockets.c
Normal file
147
tools/i-pi/drivers/sockets.c
Normal file
@ -0,0 +1,147 @@
|
||||
/* A minimal wrapper for socket communication.
|
||||
|
||||
Copyright (C) 2013, Joshua More and Michele Ceriotti
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
Contains both the functions that transmit data to the socket and read the data
|
||||
back out again once finished, and the function which opens the socket initially.
|
||||
Can be linked to a FORTRAN code that does not support sockets natively.
|
||||
|
||||
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 error(const char *msg)
|
||||
// Prints an error message and then exits.
|
||||
{ perror(msg); exit(-1); }
|
||||
|
||||
void open_socket_(int *psockfd, int* inet, int* port, char* host)
|
||||
/* 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.
|
||||
inet: An integer that determines whether the socket will be an inet or unix
|
||||
domain socket. Gives unix if 0, inet otherwise.
|
||||
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, portno, n;
|
||||
struct hostent *server;
|
||||
|
||||
struct sockaddr * psock; int ssock;
|
||||
|
||||
if (*inet>0)
|
||||
{ // creates an internet socket
|
||||
struct sockaddr_in serv_addr; psock=(struct sockaddr *)&serv_addr; ssock=sizeof(serv_addr);
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) error("Error opening socket");
|
||||
|
||||
server = gethostbyname(host);
|
||||
if (server == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error opening socket: no such host %s \n", host);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
|
||||
serv_addr.sin_port = htons(*port);
|
||||
if (connect(sockfd, psock, ssock) < 0) error("Error opening socket: wrong host address, or broken connection");
|
||||
}
|
||||
else
|
||||
{ // creates a unix socket
|
||||
struct sockaddr_un serv_addr; psock=(struct sockaddr *)&serv_addr; ssock=sizeof(serv_addr);
|
||||
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sun_family = AF_UNIX;
|
||||
strcpy(serv_addr.sun_path, "/tmp/ipi_");
|
||||
strcpy(serv_addr.sun_path+9, host);
|
||||
if (connect(sockfd, psock, ssock) < 0) error("Error opening socket: wrong host address, or broken connection");
|
||||
}
|
||||
|
||||
*psockfd=sockfd;
|
||||
}
|
||||
|
||||
void writebuffer_(int *psockfd, char *data, int* plen)
|
||||
/* Writes to a socket.
|
||||
|
||||
Args:
|
||||
psockfd: The id of the socket that will be written to.
|
||||
data: The data to be written to the socket.
|
||||
plen: The length of the data in bytes.
|
||||
*/
|
||||
|
||||
{
|
||||
int n;
|
||||
int sockfd=*psockfd;
|
||||
int len=*plen;
|
||||
|
||||
n = write(sockfd,data,len);
|
||||
if (n < 0) error("Error writing to socket: server has quit or connection broke");
|
||||
}
|
||||
|
||||
|
||||
void readbuffer_(int *psockfd, char *data, int* plen)
|
||||
/* Reads from a socket.
|
||||
|
||||
Args:
|
||||
psockfd: The id of the socket that will be read from.
|
||||
data: The storage array for data read from the socket.
|
||||
plen: The length of the data in bytes.
|
||||
*/
|
||||
|
||||
{
|
||||
int n, nr;
|
||||
int sockfd=*psockfd;
|
||||
int len=*plen;
|
||||
|
||||
n = nr = read(sockfd,data,len);
|
||||
|
||||
while (nr>0 && n<len )
|
||||
{ nr=read(sockfd,&data[n],len-n); n+=nr; }
|
||||
|
||||
if (n == 0) error("Error reading from socket: server has quit or connection broke");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user