Actual source code: send.c
1: /* $Id: send.c,v 1.123 2001/04/10 19:34:04 bsmith Exp $ */
3: #include petsc.h
4: #include petscsys.h
6: #if defined(PETSC_NEEDS_UTYPE_TYPEDEFS)
7: /* Some systems have inconsistent include files that use but do not
8: ensure that the following definitions are made */
9: typedef unsigned char u_char;
10: typedef unsigned short u_short;
11: typedef unsigned short ushort;
12: typedef unsigned int u_int;
13: typedef unsigned long u_long;
14: #endif
16: #include <errno.h>
17: #if defined(PETSC_HAVE_STDLIB_H)
18: #include <stdlib.h>
19: #endif
20: #include <sys/types.h>
21: #include <ctype.h>
22: #if defined(PETSC_HAVE_MACHINE_ENDIAN_H)
23: #include <machine/endian.h>
24: #endif
25: #if defined(PETSC_HAVE_UNISTD_H)
26: #include <unistd.h>
27: #endif
28: #if !defined(PARCH_win32)
29: #include <sys/socket.h>
30: #include <sys/wait.h>
31: #include <netinet/in.h>
32: #include <netdb.h>
33: #include <fcntl.h>
34: #if defined(PETSC_HAVE_STROPTS_H)
35: #include <stropts.h>
36: #endif
37: #if defined (PETSC_HAVE_IO_H)
38: #include <io.h>
39: #endif
41: #include src/sys/src/viewer/impls/socket/socket.h
42: #include "petscfix.h"
44: EXTERN_C_BEGIN
45: #if defined(PETSC_NEED_CLOSE_PROTO)
46: extern int close(int);
47: #endif
48: #if defined(PETSC_NEED_SOCKET_PROTO)
49: extern int socket(int,int,int);
50: #endif
51: #if defined(PETSC_NEED_SLEEP_PROTO)
52: extern int sleep(unsigned);
53: #endif
54: #if defined(PETSC_NEED_CONNECT_PROTO)
55: extern int connect(int,struct sockaddr *,int);
56: #endif
57: EXTERN_C_END
59: /*--------------------------------------------------------------*/
60: #undef __FUNCT__
62: static int PetscViewerDestroy_Socket(PetscViewer viewer)
63: {
64: PetscViewer_Socket *vmatlab = (PetscViewer_Socket*)viewer->data;
65: int ierr;
68: if (vmatlab->port) {
69: close(vmatlab->port);
70: if (ierr) SETERRQ(PETSC_ERR_LIB,"System error closing socket");
71: }
72: PetscFree(vmatlab);
73: return(0);
74: }
76: /*--------------------------------------------------------------*/
77: #undef __FUNCT__
79: int SOCKCall_Private(char *hostname,int portnum,int *t)
80: {
81: #if !defined(PETSC_MISSING_SOCKETS)
82: struct sockaddr_in sa;
83: struct hostent *hp;
84: int s = 0,ierr;
85: PetscTruth flg = PETSC_TRUE;
86: #endif
89: #if defined(PETSC_MISSING_SOCKETS)
90: SETERRQ(1,"This system does not support Unix tcp/ip");
91: #else
92: if (!(hp=gethostbyname(hostname))) {
93: perror("SEND: error gethostbyname: ");
94: SETERRQ1(PETSC_ERR_LIB,"system error open connection to %s",hostname);
95: }
96: PetscMemzero(&sa,sizeof(sa));
97: PetscMemcpy(&sa.sin_addr,hp->h_addr,hp->h_length);
99: sa.sin_family = hp->h_addrtype;
100: sa.sin_port = htons((u_short) portnum);
101: while (flg) {
102: if ((s=socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) {
103: perror("SEND: error socket"); SETERRQ(PETSC_ERR_LIB,"system error");
104: }
105: if (connect(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) {
106: if (errno == EADDRINUSE) {
107: (*PetscErrorPrintf)("SEND: address is in usen");
108: }
109: #if !defined(PARCH_win32_gnu)
110: else if (errno == EALREADY) {
111: (*PetscErrorPrintf)("SEND: socket is non-blocking n");
112: }
113: else if (errno == EISCONN) {
114: (*PetscErrorPrintf)("SEND: socket already connectedn");
115: sleep((unsigned) 1);
116: }
117: #endif
118: else if (errno == ECONNREFUSED) {
119: /* (*PetscErrorPrintf)("SEND: forcefully rejectedn"); */
120: sleep((unsigned) 1);
121: } else {
122: perror(NULL); SETERRQ(PETSC_ERR_LIB,"system error");
123: }
124: flg = PETSC_TRUE; close(s);
125: }
126: else flg = PETSC_FALSE;
127: }
128: *t = s;
129: #endif
130: return(0);
131: }
133: #undef __FUNCT__
135: /*@C
136: PetscViewerSocketOpen - Opens a connection to a Matlab or other socket
137: based server.
139: Collective on MPI_Comm
141: Input Parameters:
142: + comm - the MPI communicator
143: . machine - the machine the server is running on
144: - port - the port to connect to, use PETSC_DEFAULT for the default
146: Output Parameter:
147: . lab - a context to use when communicating with the server
149: Level: intermediate
151: Notes:
152: Most users should employ the following commands to access the
153: Matlab PetscViewers
154: $
155: $ PetscViewerSocketOpen(MPI_Comm comm, char *machine,int port,PetscViewer &viewer)
156: $ MatView(Mat matrix,PetscViewer viewer)
157: $
158: $ or
159: $
160: $ PetscViewerSocketOpen(MPI_Comm comm,char *machine,int port,PetscViewer &viewer)
161: $ VecView(Vec vector,PetscViewer viewer)
163: Options Database Keys:
164: For use with the default Matlab PetscViewer, PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF,
165: PETSC_VIEWER_SOCKET_() or if
166: PETSC_NULL is passed for machine or PETSC_DEFAULT is passed for port
167: $ -viewer_socket_machine <machine>
168: $ -viewer_socket_port <port>
170: Environmental variables:
171: + PETSC_VIEWER_SOCKET_PORT portnumber
172: - PETSC_VIEWER_SOCKET_MACHINE machine name
174: Currently the only socket client available is Matlab. See
175: src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage.
177: Concepts: Matlab^sending data
178: Concepts: sockets^sending data
180: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerSetType(),
181: PetscViewerSocketSetConnection(), PETSC_VIEWER_SOCKET_, PETSC_VIEWER_SOCKET_WORLD,
182: PETSC_VIEWER_SOCKET_SELF
183: @*/
184: int PetscViewerSocketOpen(MPI_Comm comm,const char machine[],int port,PetscViewer *lab)
185: {
189: PetscViewerCreate(comm,lab);
190: PetscViewerSetType(*lab,PETSC_VIEWER_SOCKET);
191: PetscViewerSocketSetConnection(*lab,machine,port);
192: return(0);
193: }
195: #undef __FUNCT__
197: int PetscViewerSetFromOptions_Socket(PetscViewer v)
198: {
199: int ierr,def = -1;
200: char sdef[256];
201: PetscTruth tflg;
204: /*
205: These options are not processed here, they are processed in PetscViewerSocketSetConnection(), they
206: are listed here for the GUI to display
207: */
208: PetscOptionsHead("Socket PetscViewer Options");
209: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_PORT",sdef,16,&tflg);
210: if (tflg) {
211: PetscOptionsAtoi(sdef,&def);
212: } else {
213: def = DEFAULTPORT;
214: }
215: PetscOptionsInt("-viewer_socket_port","Port number to use for socket","PetscViewerSocketSetConnection",def,0,0);
217: PetscOptionsString("-viewer_socket_machine","Machine to use for socket","PetscViewerSocketSetConnection",sdef,0,0,0);
218: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_MACHINE",sdef,256,&tflg);
219: if (!tflg) {
220: PetscGetHostName(sdef,256);
221: }
222: PetscOptionsTail();
223: return(0);
224: }
226: EXTERN_C_BEGIN
227: #undef __FUNCT__
229: int PetscViewerCreate_Socket(PetscViewer v)
230: {
231: PetscViewer_Socket *vmatlab;
232: int ierr;
235: ierr = PetscNew(PetscViewer_Socket,&vmatlab);
236: vmatlab->port = 0;
237: v->data = (void*)vmatlab;
238: v->ops->destroy = PetscViewerDestroy_Socket;
239: v->ops->flush = 0;
240: v->ops->setfromoptions = PetscViewerSetFromOptions_Socket;
241: return(0);
242: }
243: EXTERN_C_END
245: #undef __FUNCT__
247: /*@C
248: PetscViewerSocketSetConnection - Sets the machine and port that a PETSc socket
249: viewer is to use
251: Collective on PetscViewer
253: Input Parameters:
254: + v - viewer to connect
255: . machine - host to connect to
256: - port - the port on the machine one is connecting to
258: Level: advanced
260: .seealso: PetscViewerSocketOpen()
261: @*/
262: int PetscViewerSocketSetConnection(PetscViewer v,const char machine[],int port)
263: {
264: int ierr,rank;
265: char mach[256];
266: PetscTruth tflg;
267: PetscViewer_Socket *vmatlab = (PetscViewer_Socket *)v->data;
270: if (port <= 0) {
271: char portn[16];
272: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_PORT",portn,16,&tflg);
273: if (tflg) {
274: PetscOptionsAtoi(portn,&port);
275: } else {
276: port = DEFAULTPORT;
277: }
278: }
279: if (!machine) {
280: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_MACHINE",mach,256,&tflg);
281: if (!tflg) {
282: PetscGetHostName(mach,256);
283: }
284: } else {
285: PetscStrncpy(mach,machine,256);
286: }
288: MPI_Comm_rank(v->comm,&rank);
289: if (!rank) {
290: PetscLogInfo(0,"PetscViewerSocketSetConnection:Connecting to socket process on port %d machine %sn",port,mach);
291: SOCKCall_Private(mach,port,&vmatlab->port);
292: }
293: return(0);
294: }
296: /* ---------------------------------------------------------------------*/
297: /*
298: The variable Petsc_Viewer_Socket_keyval is used to indicate an MPI attribute that
299: is attached to a communicator, in this case the attribute is a PetscViewer.
300: */
301: static int Petsc_Viewer_Socket_keyval = MPI_KEYVAL_INVALID;
303: /*MC
304: PETSC_VIEWER_SOCKET_WORLD - same as PETSC_VIEWER_SOCKET_(PETSC_COMM_WORLD)
306: Level: intermediate
307: M*/
309: /*MC
310: PETSC_VIEWER_SOCKET_SELF - same as PETSC_VIEWER_SOCKET_(PETSC_COMM_SELF)
312: Level: intermediate
313: M*/
315: #undef __FUNCT__
317: /*@C
318: PETSC_VIEWER_SOCKET_ - Creates a socket viewer shared by all processors
319: in a communicator.
321: Collective on MPI_Comm
323: Input Parameter:
324: . comm - the MPI communicator to share the socket PetscViewer
326: Level: intermediate
328: Options Database Keys:
329: For use with the default Matlab PetscViewer, PETSC_VIEWER_SOCKET_WORLD or if
330: PETSC_NULL is passed for machine or PETSC_DEFAULT is passed for port
331: $ -viewer_socket_machine <machine>
332: $ -viewer_socket_port <port>
334: Environmental variables:
335: + PETSC_VIEWER_SOCKET_PORT portnumber
336: - PETSC_VIEWER_SOCKET_MACHINE machine name
338: Notes:
339: Unlike almost all other PETSc routines, PetscViewer_SOCKET_ does not return
340: an error code. The socket PetscViewer is usually used in the form
341: $ XXXView(XXX object,PETSC_VIEWER_SOCKET_(comm));
343: Currently the only socket client available is Matlab. See
344: src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage.
346: Connects to a waiting socket and stays connected until PetscViewerDestroy() is called.
348: .seealso: PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF, PetscViewerSocketOpen(), PetscViewerCreate(),
349: PetscViewerSocketSetConnection(), PetscViewerDestroy(), PETSC_VIEWER_SOCKET_()
350: @*/
351: PetscViewer PETSC_VIEWER_SOCKET_(MPI_Comm comm)
352: {
353: int ierr;
354: PetscTruth flg;
355: PetscViewer viewer;
358: if (Petsc_Viewer_Socket_keyval == MPI_KEYVAL_INVALID) {
359: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Socket_keyval,0);
360: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
361: }
362: MPI_Attr_get(comm,Petsc_Viewer_Socket_keyval,(void **)&viewer,(int *)&flg);
363: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
364: if (!flg) { /* PetscViewer not yet created */
365: PetscViewerSocketOpen(comm,0,0,&viewer);
366: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
367: PetscObjectRegisterDestroy((PetscObject)viewer);
368: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
369: MPI_Attr_put(comm,Petsc_Viewer_Socket_keyval,(void*)viewer);
370: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
371: }
372: PetscFunctionReturn(viewer);
373: }
375: #else /* defined (PARCH_win32) */
376:
377: #include petscviewer.h
378: #undef __FUNCT__
380: int PetscViewerSocketOpen(MPI_Comm comm,const char machine[],int port,PetscViewer *lab)
381: {
383: return(0);
384: }
385: #undef __FUNCT__
387: PetscViewer PETSC_VIEWER_SOCKET_(MPI_Comm comm)
388: {
390: return(0);
391: }
392: EXTERN_C_BEGIN
393: #undef __FUNCT__
395: int PetscViewerCreate_Socket(PetscViewer v)
396: {
398: return(0);
399: }
400: EXTERN_C_END
401: #endif