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