📄 socket.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ #include <ctype.h>#include <errno.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <fcntl.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <arpa/inet.h>#include <sys/utsname.h>#include "gwlib.h"static Octstr *official_name = NULL;static Octstr *official_ip = NULL;/* * FreeBSD is not happy with our approach of allocating a sockaddr * and then filling in the fields. It has private fields that need * to be initialized to 0. This structure is used for that. */static const struct sockaddr_in empty_sockaddr_in;#ifndef UDP_PACKET_MAX_SIZE#define UDP_PACKET_MAX_SIZE (64*1024)#endifint make_server_socket(int port, const char *interface_name ){ struct sockaddr_in addr; int s; int reuse; struct hostent hostinfo; char *buff = NULL; s = socket(PF_INET, SOCK_STREAM, 0); if (s == -1) { error(errno, "socket failed"); goto error; } addr = empty_sockaddr_in; addr.sin_family = AF_INET; addr.sin_port = htons(port); if (interface_name == NULL || strcmp(interface_name, "*") == 0) addr.sin_addr.s_addr = htonl(INADDR_ANY); else { if (gw_gethostbyname(&hostinfo, interface_name, &buff) == -1) { error(errno, "gethostbyname failed"); goto error; } addr.sin_addr = *(struct in_addr *) hostinfo.h_addr; } reuse = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) == -1) { error(errno, "setsockopt failed for server address"); goto error; } if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) == -1) { error(errno, "bind failed"); goto error; } if (listen(s, 10) == -1) { error(errno, "listen failed"); goto error; } gw_free(buff); return s;error: if (s >= 0) (void) close(s); gw_free(buff); return -1;}int tcpip_connect_to_server(char *hostname, int port, const char *interface_name){ return tcpip_connect_to_server_with_port(hostname, port, 0, interface_name);}int tcpip_connect_to_server_with_port(char *hostname, int port, int our_port, const char *interface_name){ struct sockaddr_in addr; struct sockaddr_in o_addr; struct hostent hostinfo; struct hostent o_hostinfo; int s; char *buff, *buff1; buff = buff1 = NULL; s = socket(PF_INET, SOCK_STREAM, 0); if (s == -1) { error(errno, "Couldn't create new socket."); goto error; } if (gw_gethostbyname(&hostinfo, hostname, &buff) == -1) { error(errno, "gethostbyname failed"); goto error; } addr = empty_sockaddr_in; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr = *(struct in_addr *) hostinfo.h_addr; if (our_port > 0 || (interface_name != NULL && strcmp(interface_name, "*") != 0)) { int reuse; o_addr = empty_sockaddr_in; o_addr.sin_family = AF_INET; o_addr.sin_port = htons(our_port); if (interface_name == NULL || strcmp(interface_name, "*") == 0) o_addr.sin_addr.s_addr = htonl(INADDR_ANY); else { if (gw_gethostbyname(&o_hostinfo, interface_name, &buff1) == -1) { error(errno, "gethostbyname failed"); goto error; } o_addr.sin_addr = *(struct in_addr *) o_hostinfo.h_addr; } reuse = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) == -1) { error(errno, "setsockopt failed before bind"); goto error; } if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) { error(errno, "bind to local port %d failed", our_port); goto error; } } if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) == -1) { error(errno, "connect failed"); goto error; } gw_free(buff); gw_free(buff1); return s;error: error(0, "error connecting to server `%s' at port `%d'", hostname, port); if (s >= 0) close(s); gw_free(buff); gw_free(buff1); return -1;}int tcpip_connect_nb_to_server(char *hostname, int port, const char *interface_name, int *done){ return tcpip_connect_nb_to_server_with_port(hostname, port, 0, interface_name, done);}int tcpip_connect_nb_to_server_with_port(char *hostname, int port, int our_port, const char *interface_name, int *done) { struct sockaddr_in addr; struct sockaddr_in o_addr; struct hostent hostinfo; struct hostent o_hostinfo; int s; int flags,rc; char *buff, *buff1; *done = 1; buff = buff1 = NULL; s = socket(PF_INET, SOCK_STREAM, 0); if (s == -1) { error(errno, "Couldn't create new socket."); goto error; } if (gw_gethostbyname(&hostinfo, hostname, &buff) == -1) { error(errno, "gethostbyname failed"); goto error; } addr = empty_sockaddr_in; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr = *(struct in_addr *) hostinfo.h_addr; if (our_port > 0 || (interface_name != NULL && strcmp(interface_name, "*") != 0)) { int reuse; o_addr = empty_sockaddr_in; o_addr.sin_family = AF_INET; o_addr.sin_port = htons(our_port); if (interface_name == NULL || strcmp(interface_name, "*") == 0) o_addr.sin_addr.s_addr = htonl(INADDR_ANY); else { if (gw_gethostbyname(&o_hostinfo, interface_name, &buff1) == -1) { error(errno, "gethostbyname failed"); goto error; } o_addr.sin_addr = *(struct in_addr *) o_hostinfo.h_addr; } reuse = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) == -1) { error(errno, "setsockopt failed before bind"); goto error; } if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) { error(errno, "bind to local port %d failed", our_port); goto error; } } flags = fcntl(s, F_GETFL, 0); fcntl(s, F_SETFL, flags | O_NONBLOCK); if ((rc = connect(s, (struct sockaddr *) &addr, sizeof(addr))) < 0) { if (errno != EINPROGRESS) { error(errno, "nonblocking connect failed"); goto error; } } /* May be connected immediatly * (if we connecting to localhost for example) */ if (rc == 0) { *done = 0; } gw_free(buff); gw_free(buff1); return s; error: error(0, "error connecting to server `%s' at port `%d'", hostname, port); if (s >= 0) close(s); gw_free(buff); gw_free(buff1); return -1;}int write_to_socket(int socket, char *str){ size_t len; int ret; len = strlen(str); while (len > 0) { ret = write(socket, str, len); if (ret == -1) { if (errno == EAGAIN) continue; if (errno == EINTR) continue; error(errno, "Writing to socket failed"); return -1; } /* ret may be less than len, if the writing was interrupted by a signal. */ len -= ret; str += ret; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -