Actual source code: send.c
1: #include "petsc.h"
2: #include petscsys.h
4: #if defined(PETSC_NEEDS_UTYPE_TYPEDEFS)
5: /* Some systems have inconsistent include files that use but do not
6: ensure that the following definitions are made */
7: typedef unsigned char u_char;
8: typedef unsigned short u_short;
9: typedef unsigned short ushort;
10: typedef unsigned int u_int;
11: typedef unsigned long u_long;
12: #endif
14: #include <errno.h>
15: #if defined(PETSC_HAVE_STDLIB_H)
16: #include <stdlib.h>
17: #endif
18: #include <sys/types.h>
19: #include <ctype.h>
20: #if defined(PETSC_HAVE_MACHINE_ENDIAN_H)
21: #include <machine/endian.h>
22: #endif
23: #if defined(PETSC_HAVE_UNISTD_H)
24: #include <unistd.h>
25: #endif
26: #if defined(PETSC_HAVE_SYS_SOCKET_H)
27: #include <sys/socket.h>
28: #endif
29: #if defined(PETSC_HAVE_SYS_WAIT_H)
30: #include <sys/wait.h>
31: #endif
32: #if defined(PETSC_HAVE_NETINET_IN_H)
33: #include <netinet/in.h>
34: #endif
35: #if defined(PETSC_HAVE_NETDB_H)
36: #include <netdb.h>
37: #endif
38: #if defined(PETSC_HAVE_FCNTL_H)
39: #include <fcntl.h>
40: #endif
41: #if defined(PETSC_HAVE_STROPTS_H)
42: #include <stropts.h>
43: #endif
44: #if defined(PETSC_HAVE_IO_H)
45: #include <io.h>
46: #endif
47: #if defined(PETSC_HAVE_WINSOCK2_H)
48: #include <Winsock2.h>
49: #endif
51: #include src/sys/src/viewer/impls/socket/socket.h
52: #include "petscfix.h"
55: #if defined(PETSC_NEED_CLOSE_PROTO)
57: #endif
58: #if defined(PETSC_NEED_SOCKET_PROTO)
60: #endif
61: #if defined(PETSC_NEED_SLEEP_PROTO)
63: #endif
64: #if defined(PETSC_NEED_CONNECT_PROTO)
66: #endif
69: /*--------------------------------------------------------------*/
72: static PetscErrorCode PetscViewerDestroy_Socket(PetscViewer viewer)
73: {
74: PetscViewer_Socket *vmatlab = (PetscViewer_Socket*)viewer->data;
75: PetscErrorCode ierr;
78: if (vmatlab->port) {
79: #if defined(PETSC_HAVE_CLOSESOCKET)
80: closesocket(vmatlab->port);
81: #else
82: close(vmatlab->port);
83: #endif
84: if (ierr) SETERRQ(PETSC_ERR_LIB,"System error closing socket");
85: }
86: PetscFree(vmatlab);
87: return(0);
88: }
90: /*--------------------------------------------------------------*/
93: PetscErrorCode SOCKCall_Private(char *hostname,int portnum,int *t)
94: {
95: #if defined(PETSC_HAVE_SOCKET)
96: struct sockaddr_in sa;
97: struct hostent *hp;
98: int s = 0;
99: PetscErrorCode ierr;
100: PetscTruth flg = PETSC_TRUE;
101: #endif
104: #if !defined(PETSC_HAVE_SOCKET)
105: SETERRQ(PETSC_ERR_SUP_SYS,"This system does not support Unix tcp/ip");
106: #else
107: if (!(hp=gethostbyname(hostname))) {
108: perror("SEND: error gethostbyname: ");
109: SETERRQ1(PETSC_ERR_LIB,"system error open connection to %s",hostname);
110: }
111: PetscMemzero(&sa,sizeof(sa));
112: PetscMemcpy(&sa.sin_addr,hp->h_addr,hp->h_length);
114: sa.sin_family = hp->h_addrtype;
115: sa.sin_port = htons((u_short) portnum);
116: while (flg) {
117: if ((s=socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) {
118: perror("SEND: error socket"); SETERRQ(PETSC_ERR_LIB,"system error");
119: }
120: if (connect(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) {
121: #if defined(PETSC_HAVE_WSAGETLASTERROR)
122: WSAGetLastError();
123: if (ierr == WSAEADDRINUSE) {
124: (*PetscErrorPrintf)("SEND: address is in use\n");
125: } else if (ierr == WSAEALREADY) {
126: (*PetscErrorPrintf)("SEND: socket is non-blocking \n");
127: } else if (ierr == WSAEISCONN) {
128: (*PetscErrorPrintf)("SEND: socket already connected\n");
129: Sleep((unsigned) 1);
130: } else if (ierr == WSAECONNREFUSED) {
131: /* (*PetscErrorPrintf)("SEND: forcefully rejected\n"); */
132: Sleep((unsigned) 1);
133: } else {
134: perror(NULL); SETERRQ(PETSC_ERR_LIB,"system error");
135: }
136: #else
137: if (errno == EADDRINUSE) {
138: (*PetscErrorPrintf)("SEND: address is in use\n");
139: } else if (errno == EALREADY) {
140: (*PetscErrorPrintf)("SEND: socket is non-blocking \n");
141: } else if (errno == EISCONN) {
142: (*PetscErrorPrintf)("SEND: socket already connected\n");
143: sleep((unsigned) 1);
144: } else if (errno == ECONNREFUSED) {
145: /* (*PetscErrorPrintf)("SEND: forcefully rejected\n"); */
146: sleep((unsigned) 1);
147: } else {
148: perror(NULL); SETERRQ(PETSC_ERR_LIB,"system error");
149: }
150: #endif
151: flg = PETSC_TRUE;
152: #if defined(PETSC_HAVE_CLOSESOCKET)
153: closesocket(s);
154: #else
155: close(s);
156: #endif
157: }
158: else flg = PETSC_FALSE;
159: }
160: *t = s;
161: #endif
162: return(0);
163: }
165: #if defined(PETSC_HAVE_SOCKET)
168: /*@C
169: PetscViewerSocketOpen - Opens a connection to a Matlab or other socket
170: based server.
172: Collective on MPI_Comm
174: Input Parameters:
175: + comm - the MPI communicator
176: . machine - the machine the server is running on
177: - port - the port to connect to, use PETSC_DEFAULT for the default
179: Output Parameter:
180: . lab - a context to use when communicating with the server
182: Level: intermediate
184: Notes:
185: Most users should employ the following commands to access the
186: Matlab PetscViewers
187: $
188: $ PetscViewerSocketOpen(MPI_Comm comm, char *machine,int port,PetscViewer &viewer)
189: $ MatView(Mat matrix,PetscViewer viewer)
190: $
191: $ or
192: $
193: $ PetscViewerSocketOpen(MPI_Comm comm,char *machine,int port,PetscViewer &viewer)
194: $ VecView(Vec vector,PetscViewer viewer)
196: Options Database Keys:
197: For use with the default Matlab PetscViewer, PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF,
198: PETSC_VIEWER_SOCKET_() or if
199: PETSC_NULL is passed for machine or PETSC_DEFAULT is passed for port
200: $ -viewer_socket_machine <machine>
201: $ -viewer_socket_port <port>
203: Environmental variables:
204: + PETSC_VIEWER_SOCKET_PORT portnumber
205: - PETSC_VIEWER_SOCKET_MACHINE machine name
207: Currently the only socket client available is Matlab. See
208: src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage.
210: Concepts: Matlab^sending data
211: Concepts: sockets^sending data
213: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerSetType(),
214: PetscViewerSocketSetConnection(), PETSC_VIEWER_SOCKET_, PETSC_VIEWER_SOCKET_WORLD,
215: PETSC_VIEWER_SOCKET_SELF
216: @*/
217: PetscErrorCode PetscViewerSocketOpen(MPI_Comm comm,const char machine[],int port,PetscViewer *lab)
218: {
222: PetscViewerCreate(comm,lab);
223: PetscViewerSetType(*lab,PETSC_VIEWER_SOCKET);
224: PetscViewerSocketSetConnection(*lab,machine,port);
225: return(0);
226: }
230: PetscErrorCode PetscViewerSetFromOptions_Socket(PetscViewer v)
231: {
233: PetscInt def = -1;
234: char sdef[256];
235: PetscTruth tflg;
238: /*
239: These options are not processed here, they are processed in PetscViewerSocketSetConnection(), they
240: are listed here for the GUI to display
241: */
242: PetscOptionsHead("Socket PetscViewer Options");
243: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_PORT",sdef,16,&tflg);
244: if (tflg) {
245: PetscOptionsAtoi(sdef,&def);
246: } else {
247: def = DEFAULTPORT;
248: }
249: PetscOptionsInt("-viewer_socket_port","Port number to use for socket","PetscViewerSocketSetConnection",def,0,0);
251: PetscOptionsString("-viewer_socket_machine","Machine to use for socket","PetscViewerSocketSetConnection",sdef,0,0,0);
252: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_MACHINE",sdef,256,&tflg);
253: if (!tflg) {
254: PetscGetHostName(sdef,256);
255: }
256: PetscOptionsTail();
257: return(0);
258: }
263: PetscErrorCode PetscViewerCreate_Socket(PetscViewer v)
264: {
265: PetscViewer_Socket *vmatlab;
266: PetscErrorCode ierr;
269: PetscNew(PetscViewer_Socket,&vmatlab);
270: vmatlab->port = 0;
271: v->data = (void*)vmatlab;
272: v->ops->destroy = PetscViewerDestroy_Socket;
273: v->ops->flush = 0;
274: v->ops->setfromoptions = PetscViewerSetFromOptions_Socket;
275: return(0);
276: }
281: /*@C
282: PetscViewerSocketSetConnection - Sets the machine and port that a PETSc socket
283: viewer is to use
285: Collective on PetscViewer
287: Input Parameters:
288: + v - viewer to connect
289: . machine - host to connect to
290: - port - the port on the machine one is connecting to
292: Level: advanced
294: .seealso: PetscViewerSocketOpen()
295: @*/
296: PetscErrorCode PetscViewerSocketSetConnection(PetscViewer v,const char machine[],PetscInt port)
297: {
298: PetscErrorCode ierr;
299: PetscMPIInt rank;
300: char mach[256];
301: PetscTruth tflg;
302: PetscViewer_Socket *vmatlab = (PetscViewer_Socket *)v->data;
305: if (port <= 0) {
306: char portn[16];
307: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_PORT",portn,16,&tflg);
308: if (tflg) {
309: PetscOptionsAtoi(portn,&port);
310: } else {
311: port = DEFAULTPORT;
312: }
313: }
314: if (!machine) {
315: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_MACHINE",mach,256,&tflg);
316: if (!tflg) {
317: PetscGetHostName(mach,256);
318: }
319: } else {
320: PetscStrncpy(mach,machine,256);
321: }
323: MPI_Comm_rank(v->comm,&rank);
324: if (!rank) {
325: PetscLogInfo(0,"PetscViewerSocketSetConnection:Connecting to socket process on port %D machine %s\n",port,mach);
326: SOCKCall_Private(mach,(int)port,&vmatlab->port);
327: }
328: return(0);
329: }
331: /* ---------------------------------------------------------------------*/
332: /*
333: The variable Petsc_Viewer_Socket_keyval is used to indicate an MPI attribute that
334: is attached to a communicator, in this case the attribute is a PetscViewer.
335: */
336: static PetscMPIInt Petsc_Viewer_Socket_keyval = MPI_KEYVAL_INVALID;
341: /*@C
342: PETSC_VIEWER_SOCKET_ - Creates a socket viewer shared by all processors
343: in a communicator.
345: Collective on MPI_Comm
347: Input Parameter:
348: . comm - the MPI communicator to share the socket PetscViewer
350: Level: intermediate
352: Options Database Keys:
353: For use with the default Matlab PetscViewer, PETSC_VIEWER_SOCKET_WORLD or if
354: PETSC_NULL is passed for machine or PETSC_DEFAULT is passed for port
355: $ -viewer_socket_machine <machine>
356: $ -viewer_socket_port <port>
358: Environmental variables:
359: + PETSC_VIEWER_SOCKET_PORT portnumber
360: - PETSC_VIEWER_SOCKET_MACHINE machine name
362: Notes:
363: Unlike almost all other PETSc routines, PetscViewer_SOCKET_ does not return
364: an error code. The socket PetscViewer is usually used in the form
365: $ XXXView(XXX object,PETSC_VIEWER_SOCKET_(comm));
367: Currently the only socket client available is Matlab. See
368: src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage.
370: Connects to a waiting socket and stays connected until PetscViewerDestroy() is called.
372: .seealso: PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF, PetscViewerSocketOpen(), PetscViewerCreate(),
373: PetscViewerSocketSetConnection(), PetscViewerDestroy(), PETSC_VIEWER_SOCKET_()
374: @*/
375: PetscViewer PETSC_VIEWER_SOCKET_(MPI_Comm comm)
376: {
378: PetscTruth flg;
379: PetscViewer viewer;
382: if (Petsc_Viewer_Socket_keyval == MPI_KEYVAL_INVALID) {
383: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Socket_keyval,0);
384: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
385: }
386: MPI_Attr_get(comm,Petsc_Viewer_Socket_keyval,(void **)&viewer,(int*)&flg);
387: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
388: if (!flg) { /* PetscViewer not yet created */
389: PetscViewerSocketOpen(comm,0,0,&viewer);
390: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
391: PetscObjectRegisterDestroy((PetscObject)viewer);
392: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
393: MPI_Attr_put(comm,Petsc_Viewer_Socket_keyval,(void*)viewer);
394: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
395: }
396: PetscFunctionReturn(viewer);
397: }
399: #else /* !defined (PETSC_HAVE_SOCKET) */
400:
403: PetscErrorCode PetscViewerSocketOpen(MPI_Comm comm,const char machine[],int port,PetscViewer *lab)
404: {
406: return(0);
407: }
410: PetscViewer PETSC_VIEWER_SOCKET_(MPI_Comm comm)
411: {
413: return(0);
414: }
418: PetscErrorCode PetscViewerCreate_Socket(PetscViewer v)
419: {
421: return(0);
422: }
424: #endif