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: static int PetscViewerDestroy_Socket(PetscViewer viewer)
61: {
62: PetscViewer_Socket *vmatlab = (PetscViewer_Socket*)viewer->data;
63: int ierr;
66: if (vmatlab->port) {
67: close(vmatlab->port);
68: if (ierr) SETERRQ(PETSC_ERR_LIB,"System error closing socket");
69: }
70: PetscFree(vmatlab);
71: return(0);
72: }
74: /*--------------------------------------------------------------*/
75: int SOCKCall_Private(char *hostname,int portnum,int *t)
76: {
77: #if !defined(PETSC_MISSING_SOCKETS)
78: struct sockaddr_in sa;
79: struct hostent *hp;
80: int s = 0,ierr;
81: PetscTruth flg = PETSC_TRUE;
82: #endif
85: #if defined(PETSC_MISSING_SOCKETS)
86: SETERRQ(1,"This system does not support Unix tcp/ip");
87: #else
88: if (!(hp=gethostbyname(hostname))) {
89: perror("SEND: error gethostbyname: ");
90: SETERRQ1(PETSC_ERR_LIB,"system error open connection to %s",hostname);
91: }
92: PetscMemzero(&sa,sizeof(sa));
93: PetscMemcpy(&sa.sin_addr,hp->h_addr,hp->h_length);
95: sa.sin_family = hp->h_addrtype;
96: sa.sin_port = htons((u_short) portnum);
97: while (flg) {
98: if ((s=socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) {
99: perror("SEND: error socket"); SETERRQ(PETSC_ERR_LIB,"system error");
100: }
101: if (connect(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) {
102: if (errno == EADDRINUSE) {
103: (*PetscErrorPrintf)("SEND: address is in usen");
104: }
105: #if !defined(PARCH_win32_gnu)
106: else if (errno == EALREADY) {
107: (*PetscErrorPrintf)("SEND: socket is non-blocking n");
108: }
109: else if (errno == EISCONN) {
110: (*PetscErrorPrintf)("SEND: socket already connectedn");
111: sleep((unsigned) 1);
112: }
113: #endif
114: else if (errno == ECONNREFUSED) {
115: /* (*PetscErrorPrintf)("SEND: forcefully rejectedn"); */
116: sleep((unsigned) 1);
117: } else {
118: perror(NULL); SETERRQ(PETSC_ERR_LIB,"system error");
119: }
120: flg = PETSC_TRUE; close(s);
121: }
122: else flg = PETSC_FALSE;
123: }
124: *t = s;
125: #endif
126: return(0);
127: }
129: /*@C
130: PetscViewerSocketOpen - Opens a connection to a Matlab or other socket
131: based server.
133: Collective on MPI_Comm
135: Input Parameters:
136: + comm - the MPI communicator
137: . machine - the machine the server is running on
138: - port - the port to connect to, use PETSC_DEFAULT for the default
140: Output Parameter:
141: . lab - a context to use when communicating with the server
143: Level: intermediate
145: Notes:
146: Most users should employ the following commands to access the
147: Matlab PetscViewers
148: $
149: $ PetscViewerSocketOpen(MPI_Comm comm, char *machine,int port,PetscViewer &viewer)
150: $ MatView(Mat matrix,PetscViewer viewer)
151: $
152: $ or
153: $
154: $ PetscViewerSocketOpen(MPI_Comm comm,char *machine,int port,PetscViewer &viewer)
155: $ VecView(Vec vector,PetscViewer viewer)
157: Options Database Keys:
158: For use with the default Matlab PetscViewer, PetscViewer_SOCKET_WORLD or if
159: PETSC_NULL is passed for machine or PETSC_DEFAULT is passed for port
160: $ -viewer_socket_machine <machine>
161: $ -viewer_socket_port <port>
163: Environmental variables:
164: + PETSC_VIEWER_SOCKET_PORT portnumber
165: - PETSC_VIEWER_SOCKET_MACHINE machine name
167: Currently the only socket client available is Matlab. See
168: src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage.
170: Concepts: Matlab^sending data
171: Concepts: sockets^sending data
173: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerSetType(),
174: PetscViewerSocketSetConnection(), PETSC_VIEWER_SOCKET_, PETSC_VIEWER_SOCKET_WORLD,
175: PETSC_VIEWER_SOCKET_SELF
176: @*/
177: int PetscViewerSocketOpen(MPI_Comm comm,const char machine[],int port,PetscViewer *lab)
178: {
182: PetscViewerCreate(comm,lab);
183: PetscViewerSetType(*lab,PETSC_VIEWER_SOCKET);
184: PetscViewerSocketSetConnection(*lab,machine,port);
185: return(0);
186: }
188: int PetscViewerSetFromOptions_Socket(PetscViewer v)
189: {
190: int ierr,def = -1;
191: char sdef[256];
192: PetscTruth tflg;
195: /*
196: These options are not processed here, they are processed in PetscViewerSocketSetConnection(), they
197: are listed here for the GUI to display
198: */
199: PetscOptionsHead("Socket PetscViewer Options");
200: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_PORT",sdef,16,&tflg);
201: if (tflg) {
202: PetscOptionsAtoi(sdef,&def);
203: } else {
204: def = DEFAULTPORT;
205: }
206: PetscOptionsInt("-viewer_socket_port","Port number to use for socket","PetscViewerSocketSetConnection",def,0,0);
208: PetscOptionsString("-viewer_socket_machine","Machine to use for socket","PetscViewerSocketSetConnection",sdef,0,0,0);
209: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_MACHINE",sdef,256,&tflg);
210: if (!tflg) {
211: PetscGetHostName(sdef,256);
212: }
213: PetscOptionsTail();
214: return(0);
215: }
217: EXTERN_C_BEGIN
218: int PetscViewerCreate_Socket(PetscViewer v)
219: {
220: PetscViewer_Socket *vmatlab;
221: int ierr;
224: ierr = PetscNew(PetscViewer_Socket,&vmatlab);
225: vmatlab->port = 0;
226: v->data = (void*)vmatlab;
227: v->ops->destroy = PetscViewerDestroy_Socket;
228: v->ops->flush = 0;
229: v->ops->setfromoptions = PetscViewerSetFromOptions_Socket;
230: return(0);
231: }
232: EXTERN_C_END
234: int PetscViewerSocketSetConnection(PetscViewer v,const char machine[],int port)
235: {
236: int ierr,rank;
237: char mach[256];
238: PetscTruth tflg;
239: PetscViewer_Socket *vmatlab = (PetscViewer_Socket *)v->data;
242: if (port <= 0) {
243: char portn[16];
244: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_PORT",portn,16,&tflg);
245: if (tflg) {
246: PetscOptionsAtoi(portn,&port);
247: } else {
248: port = DEFAULTPORT;
249: }
250: }
251: if (!machine) {
252: PetscOptionsGetenv(v->comm,"PETSC_VIEWER_SOCKET_MACHINE",mach,256,&tflg);
253: if (!tflg) {
254: PetscGetHostName(mach,256);
255: }
256: } else {
257: PetscStrncpy(mach,machine,256);
258: }
260: MPI_Comm_rank(v->comm,&rank);
261: if (!rank) {
262: PetscLogInfo(0,"PetscViewerSocketSetConnection:Connecting to socket process on port %d machine %sn",port,mach);
263: SOCKCall_Private(mach,port,&vmatlab->port);
264: }
265: return(0);
266: }
268: /* ---------------------------------------------------------------------*/
269: /*
270: The variable Petsc_Viewer_Socket_keyval is used to indicate an MPI attribute that
271: is attached to a communicator, in this case the attribute is a PetscViewer.
272: */
273: static int Petsc_Viewer_Socket_keyval = MPI_KEYVAL_INVALID;
275: /*@C
276: PETSC_VIEWER_SOCKET_ - Creates a socket viewer shared by all processors
277: in a communicator.
279: Collective on MPI_Comm
281: Input Parameter:
282: . comm - the MPI communicator to share the socket PetscViewer
284: Level: intermediate
286: Options Database Keys:
287: For use with the default Matlab PetscViewer, PETSC_VIEWER_SOCKET_WORLD or if
288: PETSC_NULL is passed for machine or PETSC_DEFAULT is passed for port
289: $ -viewer_socket_machine <machine>
290: $ -viewer_socket_port <port>
292: Environmental variables:
293: + PETSC_VIEWER_SOCKET_PORT portnumber
294: - PETSC_VIEWER_SOCKET_MACHINE machine name
296: Notes:
297: Unlike almost all other PETSc routines, PetscViewer_SOCKET_ does not return
298: an error code. The socket PetscViewer is usually used in the form
299: $ XXXView(XXX object,PETSC_VIEWER_SOCKET_(comm));
301: Currently the only socket client available is Matlab. See
302: src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage.
304: Connects to a waiting socket and stays connected until PetscViewerDestroy() is called.
306: .seealso: PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF, PetscViewerSocketOpen(), PetscViewerCreate(),
307: PetscViewerSocketSetConnection(), PetscViewerDestroy(), PETSC_VIEWER_SOCKET_()
308: @*/
309: PetscViewer PETSC_VIEWER_SOCKET_(MPI_Comm comm)
310: {
311: int ierr;
312: PetscTruth flg;
313: PetscViewer viewer;
316: if (Petsc_Viewer_Socket_keyval == MPI_KEYVAL_INVALID) {
317: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Socket_keyval,0);
318: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
319: }
320: MPI_Attr_get(comm,Petsc_Viewer_Socket_keyval,(void **)&viewer,(int *)&flg);
321: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
322: if (!flg) { /* PetscViewer not yet created */
323: PetscViewerSocketOpen(comm,0,0,&viewer);
324: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
325: PetscObjectRegisterDestroy((PetscObject)viewer);
326: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
327: MPI_Attr_put(comm,Petsc_Viewer_Socket_keyval,(void*)viewer);
328: if (ierr) {PetscError(__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,1,1," "); viewer = 0;}
329: }
330: PetscFunctionReturn(viewer);
331: }
333: #else /* defined (PARCH_win32) */
334:
335: #include petscviewer.h
336: int PetscViewerSocketOpen(MPI_Comm comm,const char machine[],int port,PetscViewer *lab)
337: {
339: return(0);
340: }
341: PetscViewer PETSC_VIEWER_SOCKET_(MPI_Comm comm)
342: {
344: return(0);
345: }
346: EXTERN_C_BEGIN
347: int PetscViewerCreate_Socket(PetscViewer v)
348: {
350: return(0);
351: }
352: EXTERN_C_END
353: #endif