PageRenderTime 19ms CodeModel.GetById 7ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/fbus/fbus_stream_socket.c

http://ftk.googlecode.com/
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