📄 socket.cpp
字号:
/* * by balancesli * balancesli@gmail.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <assert.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/utsname.h>#include <netinet/in.h>#include <netdb.h>#include "Utils.h"#include "Socket.h"#include "dget.h"/********************* Class TSocket Impl **********/TSocket :: TSocket(const char * s){ int Len = strlen(s); Host = new char[Len + 1]; strcpy(Host, s);}TSocket :: ~TSocket(void){ delete [] Host;}char * TSocket :: GetHostName(void) const{ return Host;}void TSocket :: DispAddr(char * Addr){ u_int8_t split[4]; u_int32_t ip; u_int32_t *x = (u_int32_t *) Addr; ip = ntohl(*x); split[0] = (ip & 0xff000000) >> 24; split[1] = (ip & 0x00ff0000) >> 16; split[2] = (ip & 0x0000ff00) >> 8; split[3] = (ip & 0x000000ff); ShowMsg("%d.%d.%d.%d", split[0], split[1], split[2], split[3]);} void TSocket :: NsLookup(char * * AddrList, char * HostName){ int i; for (i = 0; AddrList[i]; i++) { ShowMsg(" : ", HostName); DispAddr(AddrList[i]); } putchar('\n');} /********************* Class TSocketCli Impl **********/TSocketCli :: TSocketCli(const char * s) : TSocket(s){// if ((ConnSockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) if ((ConnSockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror("TSocket failed"); exit(EXIT_SUCCESS); }}TSocketCli :: ~TSocketCli(void){}int TSocketCli :: GetSockfd(void) const{ return ConnSockfd; }uerr_t TSocketCli :: Connect(const int Port){ struct hostent * hp; int flags, noblock; struct sockaddr_in svraddr; int status; char * HostName = GetHostName(); // ShowMsg("Resolving %s\n", HostName); if ((hp = gethostbyname(HostName)) == NULL) { ShowMsg("Failed to resolve %s", HostName); return HOSTERR; } //NsLookup(hp->h_addr_list, hp->h_name); memset((void *)&svraddr, 0, sizeof(struct sockaddr_in)); svraddr.sin_family = hp->h_addrtype; svraddr.sin_port = htons(Port); memcpy((void *)&svraddr.sin_addr, hp->h_addr, hp->h_length); //Experimental flags = fcntl(ConnSockfd, F_GETFL, 0); if (flags != -1) noblock = fcntl(ConnSockfd, F_SETFL, flags | O_NONBLOCK); else noblock = -1; // ShowMsg("Connecting to server......."); status = connect(ConnSockfd, (struct sockaddr *)&svraddr, sizeof(struct sockaddr_in)); if(status == -1 && noblock != -1 && errno == EINPROGRESS) { fd_set writefd; struct timeval tv; FD_ZERO(&writefd); FD_SET(ConnSockfd, &writefd); tv.tv_sec = 10; tv.tv_usec = 0; status = select((ConnSockfd + 1), NULL, &writefd, NULL, &tv); if (status > 0) { socklen_t arglen = sizeof(int); if(getsockopt(ConnSockfd, SOL_SOCKET, SO_ERROR, &status, &arglen) < 0) status = errno; if (status != 0) errno = status, status = -1; if (errno == EINPROGRESS) errno = ETIMEDOUT; } else if (status == 0) errno = ETIMEDOUT, status = -1; } if(status < 0) { close(ConnSockfd); if (errno == ECONNREFUSED) return CONREFUSED; else return CONERROR; } else { flags = fcntl(ConnSockfd, F_GETFL, 0); if (flags != -1) fcntl(ConnSockfd, F_SETFL, flags & ~O_NONBLOCK); /* if (flags != -1) fcntl( ConnSockfd, F_SETFL, flags | O_NONBLOCK ); */ } return NOCONERROR;}/********************* Class TSocketSvr Impl **********/TSocketSvr :: TSocketSvr(const char * s) : TSocket(s){ }TSocketSvr :: ~TSocketSvr(void){}int TSocketSvr :: GetSockfd(void) const{ return ListenSockfd;}uerr_t TSocketSvr :: Bind(void){ struct sockaddr_in svraddr; /* * Open a TCP TSocket (an Internet stream TSocket). */ if ((ListenSockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { return CONSOCKERR; } /* * Fill in structure fields for binding */ memset((void *) &svraddr, 0, sizeof(struct sockaddr_in)); svraddr.sin_family = AF_INET; svraddr.sin_addr.s_addr = htonl(INADDR_ANY); svraddr.sin_port = htons(0); /* * bind the address to the TSocket */ if(bind(ListenSockfd, (struct sockaddr *)&svraddr, sizeof(struct sockaddr_in)) < 0) { perror("bind"); close(ListenSockfd); return BINDERR; } /* * allow only one server */ if (listen(ListenSockfd, 1) < 0) { perror("listen"); close(ListenSockfd); return LISTENERR; } return BINDOK;}uerr_t TSocketSvr :: Accept(int * DataSock){ struct sockaddr_in cliaddr; socklen_t len = sizeof(struct sockaddr_in); int skfd = accept(ListenSockfd, (struct sockaddr *)&cliaddr, &len); if (skfd < 0) { perror("accept"); return ACCEPTERR; } *DataSock = skfd; /* * now we can free the listen TSocket since it is not needed... * accept returnd the new TSocket... */ close(ListenSockfd); return ACCEPTOK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -