00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <string.h>
00027 #include <unistd.h>
00028 #include <fcntl.h>
00029 #include <netdb.h>
00030 #include <errno.h>
00031 #include <netinet/in.h>
00032 #include <arpa/inet.h>
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035 #include <sys/time.h>
00036
00037 #include "socket.h"
00038
00039
00040 socket_t
00041 socket_create (const char *addr, unsigned port)
00042 {
00043 struct sockaddr_in s_in;
00044 socket_t sock;
00045 int result;
00046 int sock_opt;
00047
00048 sock = socket (AF_INET, SOCK_STREAM, 0);
00049 if (sock < 0)
00050 return -1;
00051
00052 memset (&s_in, 0, sizeof (s_in));
00053 s_in.sin_family = PF_INET;
00054 s_in.sin_port = htons (port);
00055 s_in.sin_addr.s_addr = htonl (INADDR_ANY);
00056
00057 result = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
00058 &sock_opt, sizeof (sock_opt));
00059 if (result < 0)
00060 return -2;
00061
00062
00063 if (addr)
00064 inet_aton (addr, &s_in.sin_addr);
00065
00066 result = bind (sock, (struct sockaddr *) (&s_in), sizeof (s_in));
00067 if (result < 0)
00068 return -3;
00069
00070 return sock;
00071 }
00072
00073
00074 socket_t
00075 socket_create_server (unsigned port, fd_set * fdset)
00076 {
00077 socket_t sock = socket_create (0, port);
00078 int result;
00079
00080 if (sock < 0)
00081 return sock;
00082
00083 result = listen (sock, 5);
00084 if (result < 0)
00085 return -4;
00086
00087 FD_ZERO (fdset);
00088 FD_SET (sock, fdset);
00089
00090 return sock;
00091 }
00092
00093
00094 int
00095 socket_poll (socket_t sock, fd_set * fdset,
00096 void (*callback_newconn) (socket_t),
00097 void (*callback_data) (socket_t, char *, int),
00098 void (*callback_close) (socket_t))
00099 {
00100 static char read_buf[4097];
00101 socket_t new_sock;
00102 fd_set readset = *fdset;
00103 struct sockaddr_in s_in;
00104 struct timeval tv;
00105 socklen_t s_len;
00106 int result;
00107 int i;
00108
00109 tv.tv_sec = 0;
00110 tv.tv_usec = 300000;
00111
00112 result = select (FD_SETSIZE, &readset, 0, 0, &tv);
00113 if (result < 0)
00114 return -1;
00115
00116 for (i = 0; i < FD_SETSIZE; ++i)
00117 {
00118 if (FD_ISSET (i, &readset))
00119 {
00120 if (i == sock)
00121 {
00122
00123 s_len = sizeof (s_in);
00124 new_sock = accept (sock, (struct sockaddr *) (&s_in), &s_len);
00125 if (new_sock < 0)
00126 return -2;
00127
00128 FD_SET (new_sock, fdset);
00129 fcntl (new_sock, F_SETFL, O_NONBLOCK);
00130 callback_newconn (new_sock);
00131 }
00132 else
00133 {
00134
00135
00136 do
00137 {
00138 result = recv (i, read_buf, 4096, 0);
00139 if (result <= 0)
00140 {
00141 if (result == 0 || errno != EAGAIN)
00142 {
00143 callback_close (i);
00144 close (i);
00145 FD_CLR (i, fdset);
00146 FD_CLR (i, &readset);
00147 }
00148 }
00149 else if (result > 0)
00150 {
00151 read_buf[result] = 0;
00152 callback_data (i, read_buf, result);
00153 }
00154 }
00155 while (result > 0);
00156 }
00157 }
00158 }
00159
00160 return 0;
00161 }