tcpip_device.c

00001 /*
00002   TCP/IP 制御
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "tcpip_device.h"
00008 #include "connect_device.h"
00009 #include "detect_os.h"
00010 #include <stdlib.h>
00011 #ifdef NoSDL_Linux
00012 #include <sys/types.h>
00013 #include <sys/socket.h>
00014 #include <netinet/in.h>
00015 #include <arpa/inet.h>
00016 #include <sys/poll.h>
00017 #include <unistd.h>
00018 #include <stdio.h>
00019 #elif !HAVE_CONFIG_H || HAVE_LIBSDL_NET
00020 #include <SDL_net.h>
00021 #endif
00022 
00023 
00024 #ifndef NoSDL_Linux
00025 static int Initialized = 0;
00026 #endif
00027 typedef struct {
00028 #ifdef NoSDL_Linux
00029   struct sockaddr_in address;
00030   struct pollfd nfds;
00031 #elif !HAVE_CONFIG_H || HAVE_LIBSDL_NET
00032   TCPsocket socket;
00033   SDLNet_SocketSet set;
00034 #endif
00035 } ids_info_t;
00036 static ids_info_t ids[ID_MAX];
00037 static int last_id = 0;
00038 
00039 
00040 #ifndef NoSDL_Linux
00041 static void initTcpipDevice(void) {
00042 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
00043   if (SDLNet_Init() < 0) {
00044     return;
00045   }
00046   atexit(SDLNet_Quit);
00047   Initialized = 1;
00048 #endif
00049 }
00050 #endif
00051 
00052 
00057 int tcpip_open(const char *host, unsigned short port) {
00058 #ifdef NoSDL_Linux
00059   int len = sizeof(ids[0].address);
00060   int fd = socket(AF_INET, SOCK_STREAM, 0);
00061   int ret;
00062 
00063   ids[last_id].nfds.fd = fd;
00064   ids[last_id].address.sin_family = AF_INET;
00065   ids[last_id].address.sin_addr.s_addr = inet_addr(host);
00066   ids[last_id].address.sin_port = htons(port);
00067 
00068   ret = connect(fd, (struct sockaddr*)&ids[last_id].address, len);
00069   if (ret < 0) {
00070     perror("connect");
00071     return -1;
00072   }
00073   // poll() 用の設定
00074   ids[last_id].nfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
00075   ids[last_id].nfds.revents = 0;
00076 
00077   return last_id++;
00078 
00079 #elif !HAVE_CONFIG_H || HAVE_LIBSDL_NET
00080   IPaddress ip;
00081 
00082   if (last_id >= ID_MAX) {
00083     return -1;
00084   }
00085   ids[last_id].socket = NULL;
00086   if (!Initialized) {
00087     initTcpipDevice();
00088   }
00089 
00090   SDLNet_ResolveHost(&ip, host, port);
00091   ids[last_id].socket = SDLNet_TCP_Open(&ip);
00092   if (!ids[last_id].socket) {
00093     return DEVICE_OPEN_ERROR;
00094   }
00095 
00096   ids[last_id].set = SDLNet_AllocSocketSet(1);
00097   SDLNet_TCP_AddSocket(ids[last_id].set, ids[last_id].socket);
00098 
00099   return last_id++;
00100 #else
00101   return -1;
00102 #endif
00103 }
00104 
00105 
00106 void tcpip_close(int id) {
00107 #ifdef NoSDL_Linux
00108 #elif !HAVE_CONFIG_H || HAVE_LIBSDL_NET
00109   if (ids[id].socket) {
00110     SDLNet_FreeSocketSet(ids[id].set);
00111     SDLNet_TCP_Close(ids[id].socket);
00112     ids[id].socket = NULL;
00113   }
00114 #endif
00115 }
00116 
00117 
00118 int tcpip_is_connected(int id) {
00119 #ifdef NoSDL_Linux
00120   return ids[id].nfds.fd >= 0;
00121 #elif !HAVE_CONFIG_H || HAVE_LIBSDL_NET
00122   return (ids[id].socket) ? 1 : 0;
00123 #else
00124   return 0;
00125 #endif
00126 }
00127 
00128 
00129 int tcpip_recv(int id, char *data, int size, int timeout) {
00130 #ifdef NoSDL_Linux
00131   int fd = ids[id].nfds.fd;
00132   int filled = 0;
00133   int n;
00134 
00135   while (filled < size) {
00136     if (poll(&ids[id].nfds, 1, timeout) == 0) {
00137       break;                    // timeout
00138     }
00139     n = read(fd, &data[filled], size - filled);
00140     if (n <= 0) {
00141       break;
00142     }
00143     filled += n;
00144   }
00145   return filled;
00146 
00147 #elif !HAVE_CONFIG_H || HAVE_LIBSDL_NET
00148   int n;
00149 
00150   if (SDLNet_CheckSockets(ids[id].set, timeout) <= 0) {
00151     return 0;
00152   }
00153   if (SDLNet_SocketReady(ids[id].socket)) {
00154     n = SDLNet_TCP_Recv(ids[id].socket, data, size);
00155     if (n <= 0) {
00156       tcpip_close(id);
00157       return NO_CONNECT;
00158     }
00159   }
00160   return n;
00161 #else
00162   return 0;
00163 #endif
00164 }
00165 
00166 
00167 int tcpip_send(int id, const char *data, int length) {
00168 #ifdef NoSDL_Linux
00169   return write(ids[id].nfds.fd, data, length);
00170 #elif !HAVE_CONFIG_H || HAVE_LIBSDL_NET
00171   return SDLNet_TCP_Send(ids[id].socket, (char*)data, length);
00172 #else
00173   return 0;
00174 #endif
00175 }
00176 

Generated on Mon Apr 13 22:52:05 2009 by  doxygen 1.5.7.1