/[LeafOK_CVS]/lbbs/src/tcplib.c
ViewVC logotype

Diff of /lbbs/src/tcplib.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.1 by sysadm, Mon Mar 21 17:08:21 2005 UTC Revision 1.2 by sysadm, Mon Apr 28 03:31:00 2025 UTC
# Line 1  Line 1 
1  #include "tcplib.h"  #include "tcplib.h"
2    
3  void  void MsToTimeval(const int ms, struct timeval *tv)
 MsToTimeval (const int ms, struct timeval *tv)  
4  {  {
5    tv->tv_sec = ms / TIME_CNV_RATIO;          tv->tv_sec = ms / TIME_CNV_RATIO;
6    tv->tv_usec = (ms - tv->tv_sec * TIME_CNV_RATIO) * TIME_CNV_RATIO;          tv->tv_usec = (ms - tv->tv_sec * TIME_CNV_RATIO) * TIME_CNV_RATIO;
7  }  }
8    
9  int  int TimevalToMs(const struct timeval *tv)
10  TimevalToMs (const struct timeval *tv)  {
11  {          return (tv->tv_sec * TIME_CNV_RATIO + tv->tv_usec / TIME_CNV_RATIO);
12    return (tv->tv_sec * TIME_CNV_RATIO + tv->tv_usec / TIME_CNV_RATIO);  }
13  }  
14    void TimevalSubtract(struct timeval *ltv, const struct timeval *rtv)
15  void  {
16  TimevalSubtract (struct timeval *ltv, const struct timeval *rtv)          if (ltv->tv_usec < rtv->tv_usec)
17  {          {
18    if (ltv->tv_usec < rtv->tv_usec)                  ltv->tv_sec--;
19      {                  ltv->tv_usec += TIME_CNV_RATIO * TIME_CNV_RATIO;
20        ltv->tv_sec--;          }
21        ltv->tv_usec += TIME_CNV_RATIO * TIME_CNV_RATIO;          ltv->tv_sec -= rtv->tv_sec;
22      }          ltv->tv_usec -= rtv->tv_usec;
23    ltv->tv_sec -= rtv->tv_sec;  }
24    ltv->tv_usec -= rtv->tv_usec;  
25  }  int NonBlockConnect(int sockfd, const struct sockaddr *saptr, socklen_t salen,
26                                            const int msec)
27  int  {
28  NonBlockConnect (int sockfd, const struct sockaddr *saptr, socklen_t salen,          int flags, n, error;
29                   const int msec)          socklen_t len;
30  {          fd_set rset, wset;
31    int flags, n, error;          struct timeval tval;
32    socklen_t len;  
33    fd_set rset, wset;          /*
34    struct timeval tval;           * 设置为非阻塞的 socket
35             */
36    /*          flags = fcntl(sockfd, F_GETFL, 0);
37     * 设置为非阻塞的 socket          fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
38     */  
39    flags = fcntl (sockfd, F_GETFL, 0);          error = 0;
40    fcntl (sockfd, F_SETFL, flags | O_NONBLOCK);          if ((n = connect(sockfd, saptr, salen)) < 0)
41            {
42    error = 0;                  if (errno != EINPROGRESS)
43    if ((n = connect (sockfd, saptr, salen)) < 0)                          return ERR_TCPLIB_CONNECT; /* 连接失败 */
44      {          }
45        if (errno != EINPROGRESS)  
46          return ERR_TCPLIB_CONNECT;      /* 连接失败 */          /*
47      }           * Do whatever we want while the connect is taking place.
48             */
49    /*  
50     * Do whatever we want while the connect is taking place.          if (n == 0)
51     */                  goto done; /* connect completed immediately */
52    
53    if (n == 0)          FD_ZERO(&rset);
54      goto done;                  /* connect completed immediately */          FD_SET(sockfd, &rset);
55            wset = rset; /* structure assignment */
56    FD_ZERO (&rset);          MsToTimeval(msec, &tval);
57    FD_SET (sockfd, &rset);  
58    wset = rset;                  /* structure assignment */          n = SignalSafeSelect(sockfd + 1, &rset, &wset, NULL, msec ? &tval : NULL);
59    MsToTimeval (msec, &tval);          if (n == 0)
60            {
61    n = SignalSafeSelect (sockfd + 1, &rset, &wset, NULL, msec ? &tval : NULL);                  errno = ETIMEDOUT;
62    if (n == 0)                  return ERR_TCPLIB_TIMEOUT; /* 连接服务器超时 */
63      {          }
64        errno = ETIMEDOUT;          else if (n < 0)
65        return ERR_TCPLIB_TIMEOUT;        /* 连接服务器超时 */                  return ERR_TCPLIB_OTHERS; /* select()出错 */
66      }          if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset))
67    else if (n < 0)          {
68      return ERR_TCPLIB_OTHERS;   /* select()出错 */                  len = sizeof(error);
69    if (FD_ISSET (sockfd, &rset) || FD_ISSET (sockfd, &wset))                  if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
70      {                          return ERR_TCPLIB_OTHERS; /* Solaris pending error */
71        len = sizeof (error);          }
       if (getsockopt (sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)  
         return ERR_TCPLIB_OTHERS;       /* Solaris pending error */  
     }  
72    
73  done:  done:
74    fcntl (sockfd, F_SETFL, flags);       /* restore file status flags */          fcntl(sockfd, F_SETFL, flags); /* restore file status flags */
75    
76            if (error)
77            {
78                    errno = error;
79                    return ERR_TCPLIB_CONNECT; /* 连接服务器失败 */
80            }
81            return 0; /* 连接服务器成功 */
82    }
83    
84    if (error)  int NonBlockConnectEx(int sockfd, const struct sockaddr *saptr, socklen_t salen,
85      {                                            const int msec, const int conn)
86        errno = error;  {
87        return ERR_TCPLIB_CONNECT;        /* 连接服务器失败 */          int flags, n, error;
88      }          socklen_t len;
89    return 0;                     /* 连接服务器成功 */          fd_set rset, wset;
90  }          struct timeval tval;
91    
92  int          /*
93  NonBlockConnectEx (int sockfd, const struct sockaddr *saptr, socklen_t salen,           * 设置为非阻塞的 socket
94                     const int msec, const int conn)           */
95  {          flags = fcntl(sockfd, F_GETFL, 0);
96    int flags, n, error;          fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
97    socklen_t len;  
98    fd_set rset, wset;          error = 0;
99    struct timeval tval;          if (conn == 1)
100            {
101    /*                  if ((n = connect(sockfd, saptr, salen)) < 0)
102     * 设置为非阻塞的 socket                  {
103     */                          if (errno != EINPROGRESS)
104    flags = fcntl (sockfd, F_GETFL, 0);                                  return ERR_TCPLIB_CONNECT; /* 连接失败 */
105    fcntl (sockfd, F_SETFL, flags | O_NONBLOCK);                  }
106    
107    error = 0;                  /*
108    if (conn == 1)                   * Do whatever we want while the connect is taking place.
109      {                   */
110        if ((n = connect (sockfd, saptr, salen)) < 0)  
111          {                  if (n == 0)
112            if (errno != EINPROGRESS)                          goto done; /* connect completed immediately */
113              return ERR_TCPLIB_CONNECT;  /* 连接失败 */          }
114          }  
115            FD_ZERO(&rset);
116        /*          FD_SET(sockfd, &rset);
117         * Do whatever we want while the connect is taking place.          wset = rset; /* structure assignment */
118         */          MsToTimeval(msec, &tval);
119    
120        if (n == 0)          n = SignalSafeSelect(sockfd + 1, &rset, &wset, NULL, msec ? &tval : NULL);
121          goto done;              /* connect completed immediately */          if (n == 0)
122      }          {
123                    errno = ETIMEDOUT;
124    FD_ZERO (&rset);                  return ERR_TCPLIB_TIMEOUT; /* 连接服务器超时 */
125    FD_SET (sockfd, &rset);          }
126    wset = rset;                  /* structure assignment */          else if (n < 0)
127    MsToTimeval (msec, &tval);                  return ERR_TCPLIB_OTHERS; /* select()出错 */
128            if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset))
129    n = SignalSafeSelect (sockfd + 1, &rset, &wset, NULL, msec ? &tval : NULL);          {
130    if (n == 0)                  len = sizeof(error);
131      {                  if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
132        errno = ETIMEDOUT;                          return ERR_TCPLIB_OTHERS; /* Solaris pending error */
133        return ERR_TCPLIB_TIMEOUT;        /* 连接服务器超时 */          }
     }  
   else if (n < 0)  
     return ERR_TCPLIB_OTHERS;   /* select()出错 */  
   if (FD_ISSET (sockfd, &rset) || FD_ISSET (sockfd, &wset))  
     {  
       len = sizeof (error);  
       if (getsockopt (sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)  
         return ERR_TCPLIB_OTHERS;       /* Solaris pending error */  
     }  
134    
135  done:  done:
136    fcntl (sockfd, F_SETFL, flags);       /* restore file status flags */          fcntl(sockfd, F_SETFL, flags); /* restore file status flags */
137    
138    if (error)          if (error)
139      {          {
140        errno = error;                  errno = error;
141        return ERR_TCPLIB_CONNECT;        /* 连接服务器失败 */                  return ERR_TCPLIB_CONNECT; /* 连接服务器失败 */
142      }          }
143    return 0;                     /* 连接服务器成功 */          return 0; /* 连接服务器成功 */
144  }  }
145    
146  int  int DoConnect(const char *ip, const int port, const int msec)
147  DoConnect (const char *ip, const int port, const int msec)  {
148  {          struct sockaddr_in sa;
149    struct sockaddr_in sa;          int conn_fd;
150    int conn_fd;          int rv;
151    int rv;  
152            /*
153    /*           * assert(ip != NULL && port != 0);
154     * assert(ip != NULL && port != 0);           */
155     */  
156            /*
157    /*           * 创建 socket
158     * 创建 socket           */
159     */          if ((conn_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
160    if ((conn_fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)                  return ERR_TCPLIB_OTHERS; /* 创建 socket 失败 */
161      return ERR_TCPLIB_OTHERS;   /* 创建 socket 失败 */          /*
162    /*           * 设置 sockaddr_in 结构
163     * 设置 sockaddr_in 结构           */
164     */          bzero(&sa, sizeof(sa));
165    bzero (&sa, sizeof (sa));          sa.sin_family = AF_INET;
   sa.sin_family = AF_INET;  
166  #ifdef HAVE_INET_ATON  #ifdef HAVE_INET_ATON
167    if (inet_aton (ip, &sa.sin_addr) <= 0)          if (inet_aton(ip, &sa.sin_addr) <= 0)
168  #else  #else
169    if (inet_pton (AF_INET, ip, &sa.sin_addr) <= 0)          if (inet_pton(AF_INET, ip, &sa.sin_addr) <= 0)
170  #endif  #endif
171      return ERR_TCPLIB_OTHERS;   /* 获取服务器地址失败 */                  return ERR_TCPLIB_OTHERS; /* 获取服务器地址失败 */
172    sa.sin_port = htons (port);          sa.sin_port = htons(port);
173    /*          /*
174     * 创建连接           * 创建连接
175     */           */
176    rv = NonBlockConnect (conn_fd, (struct sockaddr *) &sa, sizeof (sa), msec);          rv = NonBlockConnect(conn_fd, (struct sockaddr *)&sa, sizeof(sa), msec);
177    if (rv < 0)          if (rv < 0)
178      {          {
179        /*                  /*
180         * 创建连接失败,关掉 socket                   * 创建连接失败,关掉 socket
181         */                   */
182        close (conn_fd);                  close(conn_fd);
183        return rv;                  return rv;
184      }          }
185    
186    return conn_fd;          return conn_fd;
187  }  }
188    
189  void  void DoDisconnect(int conn_fd)
190  DoDisconnect (int conn_fd)  {
191  {          close(conn_fd);
192    close (conn_fd);  }
193  }  
194    int SignalSafeSelect(int nfds, fd_set *rs, fd_set *ws, fd_set *es,
195  int                                           struct timeval *tv)
196  SignalSafeSelect (int nfds, fd_set * rs, fd_set * ws, fd_set * es,  {
197                    struct timeval *tv)          int rv;
198  {  
199    int rv;          while ((rv = select(nfds, rs, ws, es, tv)) < 0)
200            {
201    while ((rv = select (nfds, rs, ws, es, tv)) < 0)                  if (errno != EINTR)
202      {                          break;
203        if (errno != EINTR)          }
204          break;          return rv;
205      }  }
206    return rv;  
207  }  int SafeAccept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen)
208    {
209  int          int flags, n;
210  SafeAccept (int sockfd, struct sockaddr *cliaddr, socklen_t * addrlen)          fd_set rset;
211  {          int conn_fd = ERR_TCPLIB_OTHERS;
212    int flags, n;  
213    fd_set rset;          FD_ZERO(&rset);
214    int conn_fd = ERR_TCPLIB_OTHERS;          FD_SET(sockfd, &rset);
215            n = SignalSafeSelect(sockfd + 1, &rset, NULL, NULL, NULL);
216    FD_ZERO (&rset);          if (n < 0)
217    FD_SET (sockfd, &rset);                  return ERR_TCPLIB_OTHERS;
218    n = SignalSafeSelect (sockfd + 1, &rset, NULL, NULL, NULL);          if (FD_ISSET(sockfd, &rset))
219    if (n < 0)          {
220      return ERR_TCPLIB_OTHERS;                  /*
221    if (FD_ISSET (sockfd, &rset))                   * 设置为非阻塞的 socket
222      {                   */
223        /*                  flags = fcntl(sockfd, F_GETFL, 0);
224         * 设置为非阻塞的 socket                  fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
225         */                  /*
226        flags = fcntl (sockfd, F_GETFL, 0);                   * 然后调用 accept() 接受连接请求
227        fcntl (sockfd, F_SETFL, flags | O_NONBLOCK);                   */
228        /*                  while ((conn_fd = accept(sockfd, cliaddr, addrlen)) < 0)
229         * 然后调用 accept() 接受连接请求                  {
230         */                          /*
231        while ((conn_fd = accept (sockfd, cliaddr, addrlen)) < 0)                           * from UNPv1 Page 424
232          {                           */
233            /*                          if (errno != EWOULDBLOCK && errno != ECONNABORTED && errno != EINTR)
234             * from UNPv1 Page 424                                  break;
235             */                  }
236            if (errno != EWOULDBLOCK && errno != ECONNABORTED && errno != EINTR)                  /*
237              break;                   * 使 socket 复原
238          }                   */
239        /*                  fcntl(sockfd, F_SETFL, flags);
240         * 使 socket 复原          }
241         */          return conn_fd;
242        fcntl (sockfd, F_SETFL, flags);  }
243      }  
244    return conn_fd;  int DoSendData(int sockfd, const void *buf, const size_t len, int msec)
245  }  {
246            struct timeval tv;
247  int          fd_set wset;
248  DoSendData (int sockfd, const void *buf, const size_t len, int msec)          int rv;
249  {          int wc;
250    struct timeval tv;  
251    fd_set wset;          MsToTimeval(msec, &tv);
252    int rv;          FD_ZERO(&wset);
253    int wc;          FD_SET(sockfd, &wset);
254            rv = SignalSafeSelect(sockfd + 1, NULL, &wset, NULL, &tv);
255    MsToTimeval (msec, &tv);          if (rv < 0)
256    FD_ZERO (&wset);                  return ERR_TCPLIB_OTHERS; /* some error occured */
257    FD_SET (sockfd, &wset);          if (rv == 0)
258    rv = SignalSafeSelect (sockfd + 1, NULL, &wset, NULL, &tv);                  return ERR_TCPLIB_TIMEOUT; /* timed out */
259    if (rv < 0)          if (FD_ISSET(sockfd, &wset))
260      return ERR_TCPLIB_OTHERS;   /* some error occured */          {
261    if (rv == 0)                  /*
262      return ERR_TCPLIB_TIMEOUT;  /* timed out */                   * 一次发送所有数据
263    if (FD_ISSET (sockfd, &wset))                   */
264      {                  wc = send(sockfd, buf, len, 0);
265        /*                  return wc; /* return bytes had sent */
266         * 一次发送所有数据          }
267         */          return 0; /* nothing had sent */
268        wc = send (sockfd, buf, len, 0);  }
269        return wc;                /* return bytes had sent */  
270      }  int DoRecvData(int sockfd, void *buf, const size_t len, int msec)
271    return 0;                     /* nothing had sent */  {
272  }          struct timeval tv;
273            fd_set rset;
274  int          int rv;
275  DoRecvData (int sockfd, void *buf, const size_t len, int msec)          int rc;
276  {  
277    struct timeval tv;          MsToTimeval(msec, &tv);
278    fd_set rset;          FD_ZERO(&rset);
279    int rv;          FD_SET(sockfd, &rset);
280    int rc;          rv = SignalSafeSelect(sockfd + 1, &rset, NULL, NULL, msec ? &tv : NULL);
281            if (rv < 0)
282    MsToTimeval (msec, &tv);                  return ERR_TCPLIB_OTHERS; /* some error occured */
283    FD_ZERO (&rset);          if (rv == 0)
284    FD_SET (sockfd, &rset);                  return ERR_TCPLIB_TIMEOUT; /* timed out */
285    rv = SignalSafeSelect (sockfd + 1, &rset, NULL, NULL, msec ? &tv : NULL);          if (FD_ISSET(sockfd, &rset))
286    if (rv < 0)          {
287      return ERR_TCPLIB_OTHERS;   /* some error occured */                  /*
288    if (rv == 0)                   * 一次接收所有数据
289      return ERR_TCPLIB_TIMEOUT;  /* timed out */                   */
290    if (FD_ISSET (sockfd, &rset))                  rc = recv(sockfd, buf, len, 0);
291      {                  return rc; /* return bytes had received */
292        /*          }
293         * 一次接收所有数据          return 0; /* nothing had received */
        */  
       rc = recv (sockfd, buf, len, 0);  
       return rc;                /* return bytes had received */  
     }  
   return 0;                     /* nothing had received */  
294  }  }


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1