⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockets.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/* $Header: /home/harrison/c/tcgmsg/ipcv4.0/RCS/sockets.c,v 1.1 91/12/06 17:27:30 harrison Exp Locker: harrison $ */#include <stdio.h>#ifdef SEQUENT#include <strings.h>#else#include <string.h>#endif#if defined(SUN) || defined(ALLIANT) || defined(ENCORE) || \                    defined(SEQUENT) || defined(AIX)    || defined(NEXT)#include <sys/wait.h>#endif#ifdef AIX#include <sys/select.h>#endif#ifdef CONVEX#include <errno.h>#else#include <sys/errno.h>#endif#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <netdb.h>extern int errno;#ifdef CRAY#include <memory.h>#endif#include "sndrcv.h"#include "sndrcvP.h"long PollSocket(sock)     int sock;/*  Poll the socket for available input.  Return 1 if data is available, 0 otherwise.*/{  fd_set ready;  struct timeval timelimit;  int nready;  if (sock < 0)    return 0;again:  FD_ZERO(&ready);  FD_SET(sock, &ready);  timelimit.tv_sec = 0;  timelimit.tv_usec = 0;  nready = (long) select(sock+1, &ready, (fd_set *) NULL, (fd_set *) NULL,			 &timelimit);  if (nready < 0) {    if (errno == EINTR)      goto again;    else      Error("PollSocket: error from select",  (long) sock);  }  return nready;}void TcpNoDelay(sock)  int sock;/*  Turn off waiting for more input to improve buffering   by TCP layer ... improves performance for small messages by  a factor of 30 or more. Slightly degrades performance for  large messages.*/{  int status, level, value=1;#ifdef AIX  struct protoent *proto = getprotobyname("tcp");#else  struct protoent *proto = getprotobyname("TCP");#endif#ifdef APOLLO  if (value)    return;#endif  if (proto == (struct protoent *) NULL)    Error("TcpNoDelay: getprotobyname on TCP failed!", (long) -1);  level = proto->p_proto;  status = setsockopt(sock, level, TCP_NODELAY, &value, sizeof(int));  if (status != 0)    Error("TcpNoDelay: setsockopt failed", (long) status);}void ShutdownAll()/*    close all sockets discarding any pending data in either direction.*/{   int i;   for (i=0; i<NNODES_(); i++)      if (SR_proc_info[i].sock >= 0) {         (void) shutdown(SR_proc_info[i].sock, 2);         (void) close(SR_proc_info[i].sock);      }}int ReadFromSocket(sock, buf, lenbuf)     int sock;     char *buf;     long lenbuf;/*   Read from the socket until we get all we want.*/{   int nread, status;   status = lenbuf;   while (lenbuf > 0) {again:     if ( (nread = recv(sock, buf, (int) lenbuf, 0)) <= 0) {       if (errno == EINTR)         goto again;       else {         (void) fprintf(stderr,"sock=%d, pid=%ld, nread=%d, len=%ld\n",                               sock, NODEID_(), nread, lenbuf);         (void) fflush(stderr);         status = -1;         break;       }     }     buf += nread;     lenbuf -= nread;   }      return status;}int WriteToSocket(sock, buf, lenbuf)     int sock;     char *buf;     long lenbuf;/*  Write to the socket in packets of PACKET_SIZE bytes*/{  int status = lenbuf;  int nsent, len;    while (lenbuf > 0) {        len = (lenbuf > PACKET_SIZE) ? PACKET_SIZE : lenbuf;    nsent = send(sock, buf, (int) len, 0);        if (nsent < 0) { /* This is bad news */      (void) fprintf(stderr,"sock=%d, pid=%ld, nsent=%d, len=%ld\n",		     sock, NODEID_(), nsent, lenbuf);      (void) fflush(stderr);      status = -1; break;    }    buf += nsent;    lenbuf -= nsent;  }    return status;}void CreateSocketAndBind(sock, port)     int *sock;     int *port;/*  Create a socket, bind it to a wildcard internet name and return  the info so that its port number may be advertised*/{  int length;  struct sockaddr_in server;  int size = SR_SOCK_BUF_SIZE;  int on = 1;  length = sizeof (struct sockaddr_in);  /* Create socket */  if ( (*sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)    Error("CreateSocketAndBind: socket creation failed", (long) *sock);  if(setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, 		(char *) &on, sizeof on) == -1)	Error("CreateSocketAndBind: error from setsockopt", (long) -1);  /* Increase size of socket buffers to improve long message     performance and increase size of message that goes asynchronously */  if(setsockopt(*sock, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof size))    Error("CreateSocketAndBind: error setting SO_RCVBUF", (long) size);  if(setsockopt(*sock, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof size))    Error("CreateSocketAndBind: error setting SO_SNDBUF", (long) size);#ifndef ARDENT  TcpNoDelay(*sock);#endif  /* Name socket with wildcards */  server.sin_family = AF_INET;  server.sin_addr.s_addr = INADDR_ANY;  server.sin_port = 0;  if (bind(*sock, (struct sockaddr *) &server, length) < 0)    Error("CreateSocketAndBind: bind failed", (long) 0);  /* Find out port number etc. */  if (getsockname(*sock, (struct sockaddr *) &server, &length) < 0)    Error("CreateSocketAndBind: getsockname failed", (long) 0);  *port = ntohs(server.sin_port);}int ListenAndAccept(sock)  int sock;/*  Listen and accept a connection on the specified socket  which was created with CreateSocketAndBind*/{  fd_set ready;  struct timeval timelimit;  int msgsock, nready;  int size = SR_SOCK_BUF_SIZE;  againlist:  if (listen(sock, 1) < 0) {    if (errno == EINTR)      goto againlist;    else      Error("ListenAndAccept: listen failed", (long) 0);  }  if (DEBUG_) {    (void) printf("process %ld out of listen on socket %d\n",NODEID_(),sock);    (void) fflush(stdout);  }  /* Use select to wait for someone to try and establish a connection     so that we can add a short timeout to avoid hangs */againsel:  FD_ZERO(&ready);  FD_SET(sock, &ready);  timelimit.tv_sec = TIMEOUT_ACCEPT;  timelimit.tv_usec = 0;  nready = select(sock+1, &ready, (fd_set *) NULL, (fd_set *) NULL,		  &timelimit);  if ( (nready <= 0) && (errno == EINTR) )    goto againsel;  else if (nready < 0)    Error("ListenAndAccept: error from select",  (long) nready);  else if (nready == 0)    Error("ListenAndAccept: timeout waiting for connection",           (long) nready);  if (!FD_ISSET(sock, &ready))    Error("ListenAndAccept: out of select but not ready!", (long) nready);againacc:  msgsock = accept(sock, (struct sockaddr *) NULL, (int *) NULL);  if (msgsock == -1) {    if (errno == EINTR)      goto againacc;    else      Error("ListenAndAccept: accept failed", (long) msgsock);  }  if (DEBUG_) {    (void) printf("process %ld out of accept on socket %d\n",		  NODEID_(),msgsock);    (void) fflush(stdout);  }  /* Increase size of socket buffers to improve long message     performance and increase size of message that goes asynchronously */  if(setsockopt(msgsock, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof size))    Error("ListenAndAccept: error setting SO_RCVBUF", (long) size);  if(setsockopt(msgsock, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof size))    Error("ListenAndAccept: error setting SO_SNDBUF", (long) size);#ifndef ARDENT  TcpNoDelay(msgsock);#endif  (void) close(sock); /* will not be needing this again */  return msgsock;}int CreateSocketAndConnect(hostname, cport)     char *hostname;     char *cport;/*  Return the file descriptor of the socket which connects me to the  remote process on hostname at port in string cport  hostname = hostname of the remote process  cport    = asci string containing port number of remote socket*/{  int sock, status;  struct sockaddr_in server;  struct hostent *hp;  int on = 1;  int size = SR_SOCK_BUF_SIZE;#ifndef SGI  struct hostent *gethostbyname();#endif  /* Create socket */  if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {    (void) fprintf(stderr,"trying to connect to host=%s, port=%s\n",                   hostname, cport);    Error("CreateSocketAndConnect: socket failed",  (long) sock);  }  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 		 (char *) &on, sizeof on) == -1)	Error("CreateSocketAndConnect: error setting REUSEADDR", (long) -1);  /* Increase size of socket buffers to improve long message     performance and increase size of message that goes asynchronously */  if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof size))    Error("CreateSocketAndConnect: error setting SO_RCVBUF", (long) size);  if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof size))    Error("CreateSocketAndConnect: error setting SO_SNDBUF", (long) size);#ifndef ARDENT  TcpNoDelay(sock);#endif  /* Connect socket */  server.sin_family = AF_INET;  hp = gethostbyname(hostname);  if (hp == 0) {    (void) fprintf(stderr,"trying to connect to host=%s, port=%s\n",                   hostname, cport);    Error("CreateSocketAndConnect: gethostbyname failed", (long) 0);  }  bcopy((char *) hp->h_addr, (char *) &server.sin_addr, hp->h_length);  server.sin_port = htons((ushort) atoi(cport));againcon:  if ((status =      connect(sock, (struct sockaddr *) &server, sizeof server)) < 0) {    if (errno == EINTR)      goto againcon;    else {      (void) fprintf(stderr,"trying to connect to host=%s, port=%s\n",                   hostname, cport);      Error("CreateSocketAndConnect: connect failed", (long) status);    }  }    return sock;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -