/fbus/fbus_stream_socket.c
C | 186 lines | 119 code | 38 blank | 29 comment | 11 complexity | 1b0d901bd827d33ed272c829df035063 MD5 | raw file
1/* 2 * File: fbus_stream_socket.c 3 * Author: Li XianJing <xianjimli@hotmail.com> 4 * Brief: socket implemented stream interface. 5 * 6 * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com> 7 * 8 * Licensed under the Academic Free License version 2.1 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25/* 26 * History: 27 * ================================================================ 28 * 2010-07-25 Li XianJing <xianjimli@hotmail.com> created 29 * 30 */ 31 32#include <netdb.h> 33#include <sys/types.h> 34#include <sys/socket.h> 35#include <netinet/tcp.h> 36#include "ftk_allocator.h" 37#include "fbus_stream_socket.h" 38 39#ifdef WIN32 40#define ftk_close_socket closesocket 41#else 42#define ftk_close_socket close 43#endif 44 45typedef struct _PrivInfo 46{ 47 int sock_no; 48}PrivInfo; 49 50static int fbus_stream_socket_read(FBusStream* thiz, char* buffer, size_t len) 51{ 52 DECL_PRIV(thiz, priv); 53 54 return recv(priv->sock_no, buffer, len, 0); 55} 56 57static int fbus_stream_socket_write(FBusStream* thiz, const char* buffer, size_t len) 58{ 59 DECL_PRIV(thiz, priv); 60 61 return send(priv->sock_no, buffer, len, 0); 62} 63 64static int fbus_stream_socket_get_fd(FBusStream* thiz) 65{ 66 DECL_PRIV(thiz, priv); 67 68 return priv->sock_no; 69} 70 71static void fbus_stream_socket_destroy(FBusStream* thiz) 72{ 73 if(thiz != NULL) 74 { 75 DECL_PRIV(thiz, priv); 76 ftk_close_socket(priv->sock_no); 77 78 FTK_FREE(thiz); 79 } 80 81 return; 82} 83 84FBusStream* fbus_stream_socket_create(int sock_no) 85{ 86 FBusStream* thiz = NULL; 87 return_val_if_fail(sock_no > 0, NULL); 88 89 thiz = FTK_ZALLOC(sizeof(FBusStream) + sizeof(PrivInfo)); 90 if(thiz != NULL) 91 { 92 int opt_value = 1; 93 DECL_PRIV(thiz, priv); 94 95 thiz->read = fbus_stream_socket_read; 96 thiz->write = fbus_stream_socket_write; 97 thiz->get_fd = fbus_stream_socket_get_fd; 98 thiz->destroy = fbus_stream_socket_destroy; 99 100 setsockopt(sock_no, IPPROTO_TCP, TCP_NODELAY, &opt_value, sizeof(opt_value)); 101 setsockopt(sock_no, SOL_SOCKET, SO_KEEPALIVE, &opt_value, sizeof(opt_value)); 102 priv->sock_no = sock_no; 103 } 104 105 return thiz; 106} 107 108 109FBusStream* fbus_stream_socket_connect(const char* host, int port) 110{ 111 int sock_no = -1; 112 struct sockaddr_in addr; 113 struct hostent* hostent_ptr = NULL; 114 115 return_val_if_fail(host != NULL && port > 0, NULL); 116 117 hostent_ptr = gethostbyname(host); 118 return_val_if_fail(hostent_ptr != NULL, NULL); 119 120 addr.sin_family = PF_INET; 121 addr.sin_port = htons((unsigned short)port); 122 addr.sin_addr.s_addr = *(unsigned long*)(hostent_ptr->h_addr_list[0]); 123 124 sock_no = socket(PF_INET, SOCK_STREAM, 0); 125 126 if(connect(sock_no, (struct sockaddr*)&(addr), sizeof(addr)) == 0) 127 { 128 return fbus_stream_socket_create(sock_no); 129 } 130 else 131 { 132 perror("connect"); 133 return NULL; 134 } 135} 136 137int fbus_stream_listen(int port) 138{ 139 int opt_value = 1; 140 struct sockaddr_in addr_server = {0}; 141 int sock_listen = socket(PF_INET, SOCK_STREAM, 0); 142 return_val_if_fail(sock_listen > 0, -1); 143 144 addr_server.sin_family = PF_INET; 145 addr_server.sin_port = htons(port); 146 addr_server.sin_addr.s_addr = INADDR_ANY; 147 148 setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof(opt_value)); 149 150 if(bind(sock_listen, (struct sockaddr*)&addr_server, sizeof(addr_server)) < 0) 151 { 152 perror("bind"); 153 ftk_close_socket(sock_listen); 154 155 return -1; 156 } 157 158 if(listen(sock_listen, 5) < 0) 159 { 160 perror("listen"); 161 ftk_close_socket(sock_listen); 162 163 return -1; 164 } 165 166 return sock_listen; 167} 168 169FBusStream* fbus_socket_accept(int sock_no) 170{ 171 int addrlen = 0; 172 int sock_client = 0; 173 struct sockaddr_in addr_client = {0}; 174 175 memset(&addr_client, 0x00, sizeof(addr_client)); 176 sock_client = accept(sock_no, (struct sockaddr*)&addr_client, (socklen_t*)&addrlen); 177 return_val_if_fail(sock_client > 0, NULL); 178 179 return fbus_stream_socket_create(sock_client); 180} 181 182Ret ftk_socket_close(int sock_no) 183{ 184 return ftk_close_socket(sock_no); 185} 186