00001 #include "tcp.h"
00002
00003 #ifndef WINSOCK
00004 # include <netdb.h>
00005 # include <netinet/in.h>
00006 # include <fcntl.h>
00007 #else
00008 static int initialized = 0;
00009 static WSADATA wsaData;
00010
00011
00012
00013
00014 static inline int initialize() {
00015 if(!initialized) {
00016 if(WSAStartup(MAKEWORD(1, 1), &wsaData)) {
00017 return TCP_ERROR;
00018 }
00019 }
00020 return 0;
00021 }
00022 #endif
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 static int set_sockaddr(struct sockaddr_in *addr,
00035 const char *host, int port) {
00036 struct hostent *he;
00037
00038 if(host) {
00039
00040 he = gethostbyname(host);
00041 if(!he) {
00042 return TCP_ERROR;
00043 }
00044
00045
00046 memcpy(&addr->sin_addr, he->h_addr, he->h_length);
00047 } else {
00048
00049 addr->sin_addr.s_addr = INADDR_ANY;
00050 }
00051
00052
00053 addr->sin_family = AF_INET;
00054 addr->sin_port = htons((short) port);
00055
00056 return 0;
00057 }
00058
00059
00060
00061
00062 static TCP_SOCKET make_socket() {
00063 TCP_SOCKET sock;
00064
00065
00066 sock = socket(AF_INET, SOCK_STREAM, 0);
00067 # ifdef WINSOCK
00068 if(sock == INVALID_SOCKET) return TCP_ERROR;
00069 # else
00070 if(sock < 0) return TCP_ERROR;
00071 # endif
00072
00073 return sock;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082 TCP_CONNECTION tcp_connect(const char *host, int port) {
00083 struct sockaddr_in addr;
00084 int sock;
00085
00086 # ifdef WINSOCK
00087
00088 if(initialize() == TCP_ERROR) return TCP_ERROR;
00089 # endif
00090
00091
00092 if(set_sockaddr(&addr, host, port) == TCP_ERROR) return TCP_ERROR;
00093
00094
00095 sock = make_socket();
00096 if(sock == TCP_ERROR) return TCP_ERROR;
00097
00098
00099 # ifdef WINSOCK
00100 if(connect(sock, (struct sockaddr*) &addr, sizeof(addr)) ==
00101 SOCKET_ERROR) {
00102 # else
00103 if(connect(sock, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
00104 # endif
00105 tcp_close(sock);
00106 return TCP_ERROR;
00107 }
00108
00109 return sock;
00110 }
00111
00112
00113
00114
00115
00116 int tcp_close(TCP_CONNECTION conn) {
00117 # ifdef WINSOCK
00118 return closesocket(conn);
00119 # else
00120 return close(conn);
00121 #endif
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 int tcp_read(TCP_CONNECTION conn, void *buf, int len) {
00138 return tcp_recv(conn, buf, len, 0);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 int tcp_write(TCP_CONNECTION conn, const void *buf, int len) {
00154 return tcp_send(conn, buf, len, 0);
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 int tcp_setblocking(TCP_CONNECTION conn, int blocking) {
00178 # ifdef WINSOCK
00179 u_long arg = !blocking;
00180
00181 return ioctlsocket(conn, FIONBIO, &arg);
00182 # else
00183 int flags;
00184
00185 flags = fcntl(conn, F_GETFL, 0);
00186 if(flags < 0) return TCP_ERROR;
00187 return fcntl(conn, F_SETFL, blocking ?
00188 flags | O_NONBLOCK :
00189 flags & ~(O_NONBLOCK));
00190 # endif
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200 TCP_SOCKET tcp_listen(const char *host, int port) {
00201 struct hostent *he;
00202 struct sockaddr_in addr;
00203 int sock;
00204
00205 # ifdef WINSOCK
00206
00207 if(initialize() == TCP_ERROR) return TCP_ERROR;
00208 # endif
00209
00210
00211 if(set_sockaddr(&addr, host, port) == TCP_ERROR) return TCP_ERROR;
00212
00213
00214 sock = make_socket();
00215 if(sock == TCP_ERROR) return TCP_ERROR;
00216
00217
00218 # ifdef WINSOCK
00219 if(bind(sock, (struct sockaddr*) &addr, sizeof(addr)) ==
00220 SOCKET_ERROR || listen(sock, 3) == SOCKET_ERROR) {
00221 # else
00222 if(bind(sock, (struct sockaddr*) &addr, sizeof(addr)) < 0 ||
00223 listen(sock, 3) < 0) {
00224 # endif
00225 tcp_close(sock);
00226 return TCP_ERROR;
00227 }
00228
00229 return sock;
00230 }
00231
00232
00233
00234
00235
00236 TCP_CONNECTION tcp_accept(TCP_SOCKET sock) {
00237 # ifdef WINSOCK
00238 return accept(sock, 0, 0);
00239 # else
00240 int conn;
00241
00242 conn = accept(sock, 0, 0);
00243 return conn < 0 ? TCP_ERROR : conn;
00244 # endif
00245 }