📄 sock.c
字号:
/* * OpenMODBUS/TCP to RS-232/485 MODBUS RTU gateway * * sock.c - socket manipulation routines * * Copyright (c) 2002-2003, Victor Antonovich (avmlink@vlink.ru) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - 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. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS 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 REGENTS OR * 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. * * $Id: sock.c,v 1.1.1.1 2003/09/13 20:38:45 kapyar Exp $ */#include "sock.h"/* * Bring i/o descriptor SD to BLKMODE (if non-zero - socket is nonblocking) * * Return: RC_ERR if there some errors */int sock_set_blkmode(int sd, int blkmode){ int flags; flags = fcntl(sd, F_GETFL); if (flags == -1) return -1; flags = blkmode ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK); flags = fcntl(sd, F_SETFL, flags); return flags;}/* * Create new socket in BLKMODE mode (if non-zero - socket is nonblocking) * * Return: socket descriptor, otherwise RC_ERR if there some errors */int sock_create(int blkmode){ int sock; if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {#ifdef LOG log(0, "sock_create(): unable to create socket (%s)", strerror(errno));#endif return RC_ERR; } /* set socket to desired blocking mode */ if (sock_set_blkmode(sock, blkmode) == -1) {#ifdef LOG log(0, "sock_create(): unable to set " "server socket to nonblocking (%s)", strerror(errno));#endif return RC_ERR; } return sock;}/* * Create new server socket with SERVER_PORT, SERVER_IP - * port and address to bind the socket, * BLKMODE - blocking mode (if non-zero - socket is nonblocking) * * Return: socket descriptor, otherwise RC_ERR if there some errors */int sock_create_server(char *server_ip, unsigned short server_port, int blkmode){ struct sockaddr_in server_sockaddr; int sock_opt = 1; int server_s; /* create socket in desired blocking mode */ server_s = sock_create(blkmode); if (server_s < 0) return server_s; /* set to close socket on exec() */ if (fcntl(server_s, F_SETFD, 1) == -1) {#ifdef LOG log(0, "sock_create_server():" " can't set close-on-exec on socket (%s)", strerror(errno));#endif return RC_ERR; } /* set reuse socket address */ if (setsockopt(server_s, SOL_SOCKET, SO_REUSEADDR, (void *)&sock_opt, sizeof(sock_opt)) == -1) {#ifdef LOG log(0, "sock_create_server():" " can't set socket to SO_REUSEADDR (%s)", strerror(errno));#endif return RC_ERR; } /* ajust socket rx and tx buffer sizes */ sock_opt = SOCKBUFSIZE; if ((setsockopt(server_s, SOL_SOCKET, SO_SNDBUF, (void *)&sock_opt, sizeof(sock_opt)) == -1) || (setsockopt(server_s, SOL_SOCKET, SO_RCVBUF, (void *)&sock_opt, sizeof(sock_opt)) == -1)) {#ifdef LOG log(0, "sock_create_server():" " can't set socket TRX buffers sizes (%s)", strerror(errno));#endif return RC_ERR; } memset(&server_sockaddr, 0, sizeof(server_sockaddr)); server_sockaddr.sin_family = AF_INET; if (server_ip != NULL) inet_aton(server_ip, &server_sockaddr.sin_addr); else server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); server_sockaddr.sin_port = htons(server_port); if (bind(server_s, (struct sockaddr *) & server_sockaddr, sizeof(server_sockaddr)) == -1) {#ifdef LOG log(0, "sock_create_server():" " unable to bind() socket (%s)", strerror(errno));#endif return RC_ERR; } /* let's listen */ if (listen(server_s, BACKLOG) == -1) {#ifdef LOG log(0, "sock_create_server():" " unable to listen() on socket (%s)", strerror(errno));#endif exit(errno); } return server_s;}/* * Accept connection from SERVER_SD - server socket descriptor * and create socket in BLKMODE blocking mode * (if non-zero - socket is nonblocking) * * Return: socket descriptor, otherwise RC_ERR if there some errors; * RMT_ADDR - ptr to connection info structure */int sock_accept(int server_sd, struct sockaddr_in *rmt_addr, int blkmode){ int sd, sock_opt = SOCKBUFSIZE; int rmt_len = sizeof(struct sockaddr_in); sd = accept(server_sd, (struct sockaddr *) rmt_addr, (socklen_t *) &rmt_len); if (sd == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) /* some errors caused */#ifdef LOG log(0, "sock_accept(): error in accept() (%s)", strerror(errno));#endif return RC_ERR; } /* tune socket */ if (sock_set_blkmode(sd, blkmode) == RC_ERR) {#ifdef LOG log(0, "sock_accept(): can't set socket blocking mode (%s)", strerror(errno));#endif close(sd); return RC_ERR; } /* ajust socket rx and tx buffer sizes */ if ((setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (void *)&sock_opt, sizeof(sock_opt)) == -1) || (setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (void *)&sock_opt, sizeof(sock_opt)) == -1)) {#ifdef LOG log(0, "sock_accept():" " can't set socket TRX buffer sizes (%s)", strerror(errno));#endif return RC_ERR; } return sd;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -