int Eiger::connect (void) { const char *functionName = "connect"; if(!mSockClosed) return EXIT_SUCCESS; mSockFd = epicsSocketCreate(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(mSockFd == INVALID_SOCKET) { ERR("couldn't create socket"); return EXIT_FAILURE; } setNonBlock(true); if(::connect(mSockFd, (struct sockaddr*)&mAddress, sizeof(mAddress)) < 0) { // Connection actually failed if(errno != EINPROGRESS) { char error[MAX_BUF_SIZE]; epicsSocketConvertErrnoToString(error, sizeof(error)); ERR_ARGS("failed to connect to %s:%d [%s]", mHostname, HTTP_PORT, error); epicsSocketDestroy(mSockFd); return EXIT_FAILURE; } // Server didn't respond immediately, wait a little else { fd_set set; struct timeval tv; int ret; FD_ZERO(&set); FD_SET(mSockFd, &set); tv.tv_sec = DEFAULT_TIMEOUT_CONNECT; tv.tv_usec = 0; ret = select(mSockFd + 1, NULL, &set, NULL, &tv); if(ret <= 0) { const char *error = ret == 0 ? "TIMEOUT" : "select failed"; ERR_ARGS("failed to connect to %s:%d [%s]", mHostname, HTTP_PORT, error); epicsSocketDestroy(mSockFd); return EXIT_FAILURE; } } } setNonBlock(false); mSockClosed = false; return EXIT_SUCCESS; }
static int tcpGenericConnect(char *err, char *addr, int port, int flags) { int s; struct sockaddr_in sa; if ((s = createSocket(err, PF_INET)) == -1) { return -1; } sa.sin_family = PF_INET;/*{{{*/ sa.sin_port = htons(port); if (inet_aton(addr, &sa.sin_addr) == 0) { struct hostent *he; he = gethostbyname(addr); if (he == NULL) { setError(err, "can't resolve: %s", addr); close(s); return -1; } memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr)); } if (flags & NETWORK_CONNECT_NONBLOCK) { if(setNonBlock(err, s) != 0) { return -1; } } if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) { if (errno == EINPROGRESS && (flags & NETWORK_CONNECT_NONBLOCK)) { return s; } setError(err, "connect: %s", strerror(errno)); close(s); return -1; }/*}}}*/ return s; }
Epoll::Epoll(int fd,std::function<void(int)> worker) :m_sfd(fd),m_logger(MessageLog::getLogger()),m_worker(worker) { m_pool = new ThreadPool(m_worker); m_pool->startThreads(); if(!setNonBlock(m_sfd)) { m_logger->errLog("Cannot set server fd non-block.it is quiting...\n"); } m_efd = epoll_create(1); if(m_efd < 0) { m_logger->errLog("Cannot create a epoll fd.it is quiting...\n"); } struct epoll_event epevent; epevent.data.fd = m_sfd; epevent.events = EPOLLIN | EPOLLET; if(epoll_ctl(m_efd,EPOLL_CTL_ADD,m_sfd,&epevent) == -1) { m_logger->errLog("Cannot add server fd into epoll.It is quit...\n"); } m_nums = 1; pEvents = new struct epoll_event[1024*2]; }
int initAcceptSock (int port) { struct sockaddr_in addr; int sfd = socket (AF_INET, SOCK_STREAM, 0); if (sfd == -1){ perror ("initAcceptSock, socket error"); close (sfd); return -1; } setReuseAddr (sfd); addr.sin_family = AF_INET; addr.sin_port = htons (port); addr.sin_addr.s_addr = htonl (INADDR_ANY); if (bind(sfd, (struct sockaddr *) &addr, sizeof (addr)) == -1){ close (sfd); return -2; } listen (sfd, 5); if(setNonBlock (sfd)==-1) { perror ("doAccept, setNonBlock error"); return -1; } return sfd; }
int doAccept (int efd, int sfd) { int cfd; struct sockaddr_in cliAddr; socklen_t cliLen = sizeof (cliAddr); bzero (&cliAddr, sizeof (cliAddr)); cfd = accept (sfd, (struct sockaddr *)&cliAddr, &cliLen); if (cfd < 0){ perror ("doAccept, accept error"); return -1; } printf("\naccept ok fd(%d)\n", cfd); if(setNonBlock (cfd)==-1) { perror ("doAccept, setNonBlock error"); return -1; } if(setTcpNoDelay (cfd)==-1) { perror ("doAccept, setTcpNoDelay error"); return -1; } epoll_in_add (efd, cfd); return cfd; }
void runServer(const char *host, int port){ socketFd = socket(AF_INET, SOCK_STREAM, 0); if (socketFd < 0) { errorlog("create socket"); return; } setNonBlock(socketFd); struct sockaddr_in serverAddr; memset(&serverAddr, 0, sizeof(serverAddr)); serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = inet_addr(host); serverAddr.sin_port = htons(port); if(bindSock(socketFd, &serverAddr, sizeof(serverAddr)) < 0){ errorlog("bind socket"); return; } if (listen(socketFd, max_bind_num) < 0) { errorlog("listen socket"); return; } waitAccept(); }
int Socket::acceptAndSetNonBlock(int fd, string& rIp, short& rPort) { int sockfd = accept(fd, rIp, rPort); if ( sockfd < 0 ) return -1; setNonBlock(sockfd); return sockfd; }
int Socket::createNonBlock(bool reuse, int stream) { int type=(stream==kTCP) ? SOCK_STREAM : SOCK_DGRAM; int fd = socket(AF_INET, type, 0); if ( fd < 0 ) return fd; int on = reuse ? 1 : 0; if ( setReuseAddr(fd, on) < 0 ) return -1; if ( setNonBlock(fd) < 0 ) return -1; return fd; }
void EventTrigger::create() { int ret = ::pipe(_pipeFds); if (ret < 0) { throw std::system_error(errno, std::system_category(), "EventTrigger::create"); } // Make fd for reading nonblocking. setNonBlock(_pipeFds[0]); setFd(_pipeFds[0]); setNextAction(eIoAction::Read); }
/* * Flush pending input */ static asynStatus flushIt(void *drvPvt,asynUser *pasynUser) { ttyController_t *tty = (ttyController_t *)drvPvt; char cbuf[512]; assert(tty); asynPrint(pasynUser, ASYN_TRACE_FLOW, "%s flush\n", tty->IPDeviceName); if (tty->fd != INVALID_SOCKET) { /* * Toss characters until there are none left */ #ifndef USE_POLL setNonBlock(tty->fd, 1); #endif while (recv(tty->fd, cbuf, sizeof cbuf, 0) > 0) continue; #ifndef USE_POLL setNonBlock(tty->fd, 0); #endif } return asynSuccess; }
bool Socket::bindImpl(const std::string& hostname,int port) { close(); addrinfo* p=getAddrInfo(hostname.c_str(),port,false); for(;p != 0; p = p->ai_next) { m_socket=socket(p->ai_family,p->ai_socktype,p->ai_protocol); if(m_socket == int(INVALID_SOCKET)) { std::cerr<<"Cannot create a socket: "<<getErrorMessage()<<std::endl; continue; } if(::bind(m_socket,p->ai_addr,p->ai_addrlen)==SOCKET_ERROR) { std::cerr<<"Cannot bind to port "<<port<<": "<<getErrorMessage()<<std::endl; close(); continue; } break; } freeAddrInfo(p); if(!p) { std::cerr<<"Cannot create a socket: "<<getErrorMessage()<<std::endl; return false; } if(listen(m_socket,10)==SOCKET_ERROR) { std::cerr<<"Cannot listen socket:"<<getErrorMessage()<<std::endl; close(); return false; } if(setNonBlock(m_socket) == false) { std::cerr<<"Cannot set socket to non-blocking mode: "<<getErrorMessage()<<std::endl; close(); return false; } return true; }
//use epoll() void Epoll::wait() { struct epoll_event epevent; int nfds = 0; for(;;) { nfds = epoll_wait(m_efd,pEvents,m_nums,-1); // no timeout for(int i=0;i<nfds;++i) { //new connection. if(( pEvents[i].data.fd == m_sfd) && pEvents[i].events & EPOLLIN) { //not need IP in this version int client = accept(m_sfd,0,0); m_logger->messageLog("A new client connected.\n"); // if this client can not connect,ignore this. if(client == -1) continue; if(setNonBlock(client)) { epevent.data.fd = client; epevent.events = EPOLLIN|EPOLLET|EPOLLONESHOT|EPOLLRDHUP|EPOLLERR;//Edge Triggered if(epoll_ctl(m_efd,EPOLL_CTL_ADD,client,&epevent) == -1) continue;//ignore this too. //m_logger->messageLog("A new client.\n"); } // if cannot set the client fd non-block,ignore too. } //new request else if(pEvents[i].events &EPOLLIN) { m_pool->addTask(pEvents[i].data.fd); } //EPOLLRDHUP or EPOLLERR else { if(epoll_ctl(m_efd,EPOLL_CTL_DEL,pEvents[i].data.fd,&pEvents[i])==-1) { m_logger->warningLog("A client cannot be remove.\n"); } close(pEvents[i].data.fd); } } } }
int fcgi_accept(int argc, char* argv[]) { // fprintf(stderr, "count = %d\n", ++count); if(!is_init) fcgi_init(argc, argv); close(STDIN_FILENO); close(STDOUT_FILENO); int connfd = tcpAccept(NEW_FCGI_LISTEN_FD); // fprintf(stderr, "connfd = %d\n", connfd); assert(connfd >= 0); setNonBlock(connfd, false); struct Buffer* input = newBuffer(); // fprintf(stderr, "before read\n"); int n = bufferRead(input, connfd); fprintf(stderr, "n = %d\n", n); // fprintf(stderr, "after read\n"); char* line; //init environment while( (line = readLine(input)) != NULL && line[0] != '\0') { if(strlen(line) > 0) { // fprintf(stderr, "%s\n", line); putenv(line); } } freeBuffer(input); dup2(connfd, STDIN_FILENO); dup2(connfd, STDOUT_FILENO); setbuf(stdin, NULL); setbuf(stdout, NULL); // fprintf(stderr, "fcgi accept over. \n"); return 0; }
bool Socket::connectImpl(const std::string& hostname,const int port) { close(); addrinfo* p=getAddrInfo(hostname.c_str(),port,false); if(!p) return false; std::string errormsg; for(;p != 0; p = p->ai_next) { m_socket=socket(p->ai_family,p->ai_socktype,p->ai_protocol); if(m_socket == int(INVALID_SOCKET)) continue; if(::connect(m_socket,p->ai_addr,p->ai_addrlen) == SOCKET_ERROR) { errormsg=getErrorMessage(); close(); continue; } break; } freeAddrInfo(p); if(!p) { std::cerr<<"Cannot connect to \""<<hostname<<"\" port "<<port<<": "<<errormsg<<std::endl; return false; } if(setNonBlock(m_socket) == false) { std::cerr<<"Cannot set socket to non-blocking mode: "<<getErrorMessage()<<std::endl; close(); } return true; }
// Добавляем новое соединение в epoll int acceptConnection() { struct sockaddr addr; socklen_t addrlen = sizeof(addr); int connectionfd = accept(socketfd, &addr, &addrlen); if (connectionfd == -1) { perror("acception connection error"); return -1; } if (setNonBlock(connectionfd) == -1) { fprintf(stderr, "Making connection descriptor %d non-block error\n", connectionfd); return -1; } if (addToEpoll(epollfd, connectionfd, EPOLLET | EPOLLIN) == -1) { fprintf(stderr, "Adding connection to epoll\n"); return -1; } addConnectionIntoList(connectionfd); return connectionfd; }
bool Socket::acceptImpl(int& socket) { if(m_socket == int(INVALID_SOCKET)) return false; int newsocket; newsocket = ::accept(m_socket, 0, 0); if(newsocket == int(INVALID_SOCKET)) { #ifdef WIN32 if(WSAGetLastError()!=WSAEWOULDBLOCK) #else if(errno!=EWOULDBLOCK) #endif { std::cerr<<"accept failed: "<<getErrorMessage()<<std::endl; } return false; } if(setNonBlock(newsocket) == false) { std::cerr<<"Cannot set socket to non-blocking mode: "<<getErrorMessage()<<std::endl; #ifdef WIN32 closesocket(newsocket); #else ::close(newsocket); #endif return false; } socket=newsocket; return true; }
const int socketer::accetper() { //int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); int acceptfd = accept(fd_, (struct sockaddr*)NULL, NULL); // printf("accept socket error: %s(errno: %d)",strerror(errno),errno); //continue; printf("listfd=%d,clinetfd=%d\n",fd_,acceptfd); if (acceptfd >= 0) { setNonBlock(acceptfd); // handleSocket = new Socket(); // handleSocket->setUp(fd, (struct sockaddr *)&addr); } else { int error = getLastError(); if (error != EAGAIN) { printf("accept socket error: %s(errno: %d)",strerror(errno),errno); } } //setNonBlock(acceptfd); return acceptfd; }
// прием соединения, если новых соединений нет или произошла ошибка то connectionfd == -1 int acceptConnection(int epollfd, int socketfd, struct UserParams userParams){ struct sockaddr addr; socklen_t addrlen = sizeof addr; int connectionfd = accept(socketfd, &addr, &addrlen); if (connectionfd == -1){ perror ("failed to accept connection"); return -1; } char host[NI_MAXHOST]; char service[NI_MAXSERV]; //резервирование символьного адреса и имени сервиса if(!getnameinfo(&addr, addrlen, host, sizeof host, service, sizeof service, NI_NUMERICHOST | NI_NUMERICSERV)){ //вывод информации о полльзователе printf("new connection: %s:%s\n", host, service); } if (setNonBlock(connectionfd) == -1){ fprintf(stderr, "failed to set socket %d nonblock", connectionfd); return -1; } //добавление в epol if (addToEpoll(epollfd, connectionfd) == -1){ fprintf(stderr, "failed to add socket %d to epoll", connectionfd); return -1; } dprintf(connectionfd,"Enter login: "******"%d",connectionfd); DictInsert(userParams.login, conBuf, ""); snprintf(conBuf, 4,"%d",connectionfd); DictInsert(userParams.fLogin, conBuf, "0"); return 0; }
// Establish a regular tcp connection static int tcpConnect(const char* ip, short port) { int handle = socket(AF_INET, SOCK_STREAM, 0); check1(handle >= 0, SSLERR_CONNECT, "socket return error"); setNonBlock(handle, 1); struct sockaddr_in server; bzero(&server, sizeof server); server.sin_family = AF_INET; server.sin_port = htons(port); char *newIP = formatIP(ip); inet_aton(ip, (struct in_addr *)&server.sin_addr.s_addr); free(newIP); int r = connect(handle, (struct sockaddr *) &server, sizeof(struct sockaddr)); if (r < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { struct pollfd pfd; pfd.fd = handle; pfd.events = POLLOUT | POLLERR; while (r == 0) { r = poll(&pfd, 1, 100); } check1(pfd.revents == POLLOUT, SSLERR_CONNECT, "poll return error events: %d", pfd.revents); } return handle; }
int socketAccept(int sockfd, struct sockaddr_in * addr) { socklen_t addrlen = sizeof *addr; int connfd = accept(sockfd, (struct sockaddr *)addr, &addrlen); setNonBlock(connfd); if(connfd < 0) { int savedErrno = errno; switch(connfd) { case EAGAIN: case ECONNABORTED: case EINTR: case EPROTO: case EPERM: case EMFILE: errno = savedErrno; break; case EBADF: case EFAULT: case EINVAL: case ENFILE: case ENOBUFS: case ENOMEM: case ENOTSOCK: case EOPNOTSUPP: fprintf(stderr, "unexpected error : %d\n", savedErrno); break; default: fprintf(stderr, "unkown error : %d\n", savedErrno); break; } } return connfd; }
static void* clientThreadEntry(void *arg) { int clientSocket = *static_cast<int*>(arg); free(arg); if(!setNonBlock(clientSocket)) { printf("setNonBlock failed\n"); close(clientSocket); return nullptr; } TransferRingBuffer tBuf(BUF_SIZE); while(true) { void *data; int size; if(tBuf.startWrite(data, size)) { int rd = read(clientSocket, data, size); if(rd <= 0) { if(errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR) { if(rd == 0 && errno == 0) { printf("client disconnected\n"); close(clientSocket); return nullptr; } else { printf("read failed: %s\n", strerror(errno)); close(clientSocket); return nullptr; } } } else { tBuf.endWrite(rd); } } if(tBuf.startRead(data, size)) { if(withCheck) { checkBuffer(data, size); } int wr = write(clientSocket, data, size); if(wr <= 0) { if(errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR) { printf("write failed: %s\n", strerror(errno)); close(clientSocket); return nullptr; } } else { tBuf.endRead(wr); } } } }
/**************************************************************************** * * for support of ipv6: linux, mac osx, windows (xp+, dont compile in older) * getaddrinfo, freeaddrinfo, getnameinfo * * if we dont want ipv6 support we can do 2 things: * 1- write our own get/freeaddrinfo and getnameinfo * 2- use totally different code with gethostbyname, etc... * * * what we will do is, on non windows, use the ipv6_able functions * and on windows, if the user wants ipv6 support will need to define some * variable (like _ENABLE_IPV6?) or will only be able to use ipv4 and we will * use old functions (gethostbyname, inet_addr, ...) * * XXX TODO think a way to do asyn DNS * ****************************************************************************/ void NSocketX::sysResolve(const char *hostname, const char *p, SOCKET_FLAGS stype) { #ifndef _WIN32 struct addrinfo hints; struct addrinfo *address; struct addrinfo *firstaddress; memset(&hints, 0, sizeof(hints)); //hints.ai_family = AF_UNSPEC; hints.ai_family = AF_INET; hints.ai_socktype = (stype&TCP) ? SOCK_STREAM : SOCK_DGRAM; hints.ai_flags = (stype&LISTEN) ? AI_PASSIVE : 0; sys_result = getaddrinfo(hostname, p, &hints, &firstaddress); if (sys_result) { error=sys_result; // this is correct. DON'T CHANGE if (error == NET_ERROR_NONAME) { // onHostNotFoundError(); } return; // XXX check for getaddrinfo errors } for (address=firstaddress; address; address=address->ai_next) { fd = socket(address->ai_family, address->ai_socktype, address->ai_protocol); if (fd == INVALID_SOCKET) { error=GET_NET_ERROR(); continue; // use next address if cant create socket. } has_socket=true; if (!setNonBlock()) { sysClose(); break; // XXX just close? no error? } if ( ! (stype & LISTEN) ) { sys_result = connect(fd, address->ai_addr, address->ai_addrlen); if (sys_result == SOCKET_ERROR) { error=GET_NET_ERROR(); if (error != NET_ERROR_CONINPROGRESS) { sysClose(); //onConnectError(); continue; // try next address if cant connect } is_connecting=true; //add_to_list(this); break; } //add_to_list(this); // XXX may add an element when we are in the loop break; // finished the loop here } else { // wants to bind if (!setReuseAddr()) { sysClose(); break; // XXX what can we do? } sys_result = bind(fd, address->ai_addr, address->ai_addrlen); if (sys_result == SOCKET_ERROR) { error=GET_NET_ERROR(); sysClose(); //onBindError(); break; // XXX what can we do? } if (stype & TCP) { sys_result = listen(fd, 10); if (sys_result == SOCKET_ERROR) { error=GET_NET_ERROR(); sysClose(); //onListenError(); break; // XXX what can we do? } //add_to_list(this); // XXX should put some onListening()? } break; } } if (!has_socket) { printf("dont has socket %d\n", sys_result); freeaddrinfo(firstaddress); return; // XXX put some errors somewhere, but we already has, dont we? } socket_type=stype; // convert sockaddr to ipaddress and port char * memset(ipaddress, 0, NI_MAXHOST); memset(port, 0, NI_MAXSERV); sys_result = getnameinfo((const sockaddr *) address->ai_addr, address->ai_addrlen, ipaddress, NI_MAXHOST, port, NI_MAXSERV, NI_NUMERICHOST|NI_NUMERICSERV); if (sys_result) { // XXX maybe check for some errors? int hlen; hlen=strlen(hostname); memcpy(ipaddress,hostname,(hlen<NI_MAXHOST)?hlen:NI_MAXHOST-1); hlen=strlen(p); memcpy(port,p,(hlen<NI_MAXSERV)?hlen:NI_MAXSERV-1); } freeaddrinfo(firstaddress); // XXX maybe here maybe up and copy sockaddr_in? if ( !(stype & LISTEN) && !is_connecting ) // if we are here is because we are connected { onSocketReady(); } #else // for windows, no resolver struct sockaddr_in sa; sa.sin_addr.s_addr=inet_addr(hostname); if ( sa.sin_addr.s_addr == 0xffffffff) { printf("bad name\n"); return; } sa.sin_port=htons(53); if (!sa.sin_port) { printf("bad port\n"); return; } sa.sin_family=AF_INET; int socktype; if (stype == TCP || stype == LISTEN_TCP) { socktype = SOCK_STREAM; } else { socktype = SOCK_DGRAM; } fd = socket(AF_INET, socktype, 0); if ( fd == INVALID_SOCKET ) { printf("invalid socket\n"); return; } has_socket=true; if (!setNonBlock()) { sysClose(); return; // XXX just close? no error? } if (stype == TCP || stype == UDP) { sys_result = connect(fd, (const sockaddr *)&sa, sizeof(sa)); if (sys_result == SOCKET_ERROR) { error=GET_NET_ERROR(); if (error != NET_ERROR_CONINPROGRESS) { sysClose(); onConnectError(); return; // try next address if cant connect } is_connecting=true; NSocketManager::add_to_list(this); return; } NSocketManager::add_to_list(this); // XXX may add an element when we are in the loop } else { // wants to bind if (!setReuseAddr()) { sysClose(); return; // XXX what can we do? } sys_result = bind(fd, (const struct sockaddr *)&sa, sizeof(sa)); if (sys_result == SOCKET_ERROR) { error=GET_NET_ERROR(); sysClose(); onBindError(); return; // XXX what can we do? } if (stype == LISTEN_TCP) { sys_result = listen(fd, 10); if (sys_result == SOCKET_ERROR) { error=GET_NET_ERROR(); sysClose(); onListenError(); return; // XXX what can we do? } NSocketManager::add_to_list(this); // XXX should put some onListening()? } } if ( (stype == TCP || stype == UDP) && !is_connecting ) // if we are here is because we are connected onSocketReady(); // #error "Not ready for this compiler" #endif }
int createPty(struct Connection *connection) { int ptm, pts; ptm = posix_openpt(O_RDWR); if (ptm == -1) { perror("creating new plm"); return -1; } if (grantpt(ptm) == -1) { perror("granting pt access"); return -1; } if (unlockpt(ptm) == -1) { perror("unlocking pt"); return -1; } pts = open(ptsname(ptm), O_RDWR); if (pts == -1) { perror("opening pts"); return -1; } if (setNonBlock(ptm) == -1) { fprintf(stderr, "Error: making ptm non-block\n"); return -1; } if (setNonBlock(pts) == -1) { fprintf(stderr, "Error: making pts non-block\n"); return -1; } connection->ptm = ptm; if (addToEpoll(epollfd, ptm, EPOLLET | EPOLLIN) == -1) { fprintf(stderr, "Error: adding ptm to epoll\n"); return -1; } if (fork()) { if (close(pts) == -1) { perror("closing pts in parent process"); return -1; } } else { if (close(ptm) == -1) { perror("closing ptm in child process"); return -1; } struct termios oldSettings, newSettings; if (tcgetattr(pts, &oldSettings) == -1) { perror("getting old terminal settings\n"); return -1; } newSettings = oldSettings; cfmakeraw(&newSettings); if (tcsetattr(pts, TCSANOW, &newSettings) == -1) { perror("setting new terminal settings\n"); return -1; } close(0); close(1); close(2); dup(pts); dup(pts); dup(pts); close(pts); setsid(); ioctl(0, TIOCSCTTY, 1); execvp("/bin/bash", NULL); } return 0; }
bool CWSAThread::doAccept(int fd) { struct sockaddr_in addr = {0}; socklen_t addrlen = sizeof(addr); int connfd = INVALID_SOCKET; while (true) { addrlen = sizeof(addr); connfd = accept(fd, (sockaddr*)&addr, &addrlen); if (connfd == INVALID_SOCKET) { if (WSAGetLastError() != WSAEWOULDBLOCK) { LOG(_ERROR_, "CWSAThread::doAccept() error, fd=%d, error=%d", fd, WSAGetLastError()); } return true; } string peerip = fgNtoA(ntohl(addr.sin_addr.S_un.S_addr)); unsigned short port = ntohs(addr.sin_port); LOG(_INFO_, "CWSAThread::doAccept(), peerip=%s, port=%d", GETNULLSTR(peerip), port); if (!setNonBlock(connfd)) { LOG(_ERROR_, "CWSAThread::doAccept() error, fd=%d, connfd=%d", fd, connfd); closesocket(connfd); continue; } if (setsockopt(connfd, SOL_SOCKET, SO_SNDBUF, (char*)&m_sendbufsize, sizeof(m_sendbufsize)) == SOCKET_ERROR) { LOG(_ERROR_, "CWSAThread::doAccept() error, setsockopt(SO_SNDBUF=%d) failed, fd=%d, connfd=%d, error=%d", m_sendbufsize, fd, connfd, WSAGetLastError()); closesocket(connfd); continue; } if (setsockopt(connfd, SOL_SOCKET, SO_RCVBUF, (char*)&m_readbufsize, sizeof(m_readbufsize)) == SOCKET_ERROR) { LOG(_ERROR_, "CWSAThread::doAccept() error, setsockopt(SO_RCVBUF=%d) failed, fd=%d, connfd=%d, error=%d", m_readbufsize, fd, connfd, WSAGetLastError()); closesocket(connfd); continue; } int opt = 1; if (setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt)) < 0) { LOG(_ERROR_, "CWSAThread::doAccept() error, setsockopt(TCP_NODELAY) failed, fd=%d, connfd=%d, error=%d", fd, connfd, WSAGetLastError()); closesocket(connfd); continue; } SOCKET_SET* psockset = initSocketset(connfd, getIndex(), peerip, port, CLIENT_TYPE); if (!psockset) { LOG(_ERROR_, "CWSAThread::doAccept() error, initSocketset() failed, fd=%d, connfd=%d, peerip=%s, port=%d", fd, connfd, GETNULLSTR(peerip), port); closesocket(connfd); continue; } if (!createConnectServerMsg(psockset)) { LOG(_ERROR_, "CWSAThread::doAccept() error, initSocketset() failed, fd=%d, connfd=%d, peerip=%s, port=%d", fd, connfd, GETNULLSTR(peerip), port); closesocket(connfd); delete psockset; continue; } if (!addClientToWSA(psockset)) { LOG(_ERROR_, "CWSAThread::doAccept() error, addClientToWSA() failed, fd=%d, connfd=%d, peerip=%s, port=%d", fd, connfd, GETNULLSTR(peerip), port); delete psockset; closesocket(connfd); continue; } } return true; }
socketer::socketer(const char* ip,const int port):fd_(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)),ip_(ip),port_(port) { setNonBlock(fd_); }
/* * Create a link */ static asynStatus connectIt(void *drvPvt, asynUser *pasynUser) { ttyController_t *tty = (ttyController_t *)drvPvt; SOCKET fd; int i; /* * Sanity check */ assert(tty); asynPrint(pasynUser, ASYN_TRACE_FLOW, "Open connection to %s reason:%d fd:%d\n", tty->IPDeviceName, pasynUser->reason, tty->fd); if (tty->fd != INVALID_SOCKET) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s: Link already open!", tty->IPDeviceName); return asynError; } else if(tty->flags & FLAG_SHUTDOWN) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "%s: Link shutdown!", tty->IPDeviceName); return asynError; } /* If pasynUser->reason > 0) then use this as the file descriptor */ if (pasynUser->reason > 0) { fd = pasynUser->reason; } else { /* * Create the socket */ if ((fd = epicsSocketCreate(tty->farAddr.oa.sa.sa_family, tty->socketType, 0)) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't create socket: %s", strerror(SOCKERRNO)); return asynError; } /* * Enable broadcasts if so requested */ i = 1; if ((tty->flags & FLAG_BROADCAST) && (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void *)&i, sizeof i) < 0)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s socket BROADCAST option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } /* * Convert host name/number to IP address. * We delay doing this until now in case a device * has just appeared in a DNS database. */ if (tty->flags & FLAG_NEED_LOOKUP) { if(hostToIPAddr(tty->IPHostName, &tty->farAddr.oa.ia.sin_addr) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Unknown host \"%s\"", tty->IPHostName); epicsSocketDestroy(fd); return asynError; } tty->flags &= ~FLAG_NEED_LOOKUP; tty->flags |= FLAG_DONE_LOOKUP; } /* * Bind to the local IP address if it was specified. * This is a very unusual configuration */ if (tty->localAddrSize > 0) { if (bind(fd, &tty->localAddr.sa, tty->localAddrSize)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "unable to bind to local port: %s", strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } } /* * Connect to the remote host * If the connect fails, arrange for another DNS lookup in case the * problem is just that the device has DHCP'd itself an new number. */ if (tty->socketType != SOCK_DGRAM) { if (connect(fd, &tty->farAddr.oa.sa, (int)tty->farAddrSize) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't connect to %s: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); if (tty->flags & FLAG_DONE_LOOKUP) tty->flags |= FLAG_NEED_LOOKUP; return asynError; } } } i = 1; if ((tty->socketType == SOCK_STREAM) && (tty->farAddr.oa.sa.sa_family == AF_INET) && (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&i, sizeof i) < 0)) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s socket NODELAY option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } #ifdef USE_POLL if (setNonBlock(fd, 1) < 0) { epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, "Can't set %s O_NONBLOCK option: %s", tty->IPDeviceName, strerror(SOCKERRNO)); epicsSocketDestroy(fd); return asynError; } #endif asynPrint(pasynUser, ASYN_TRACE_FLOW, "Opened connection to %s\n", tty->IPDeviceName); tty->fd = fd; return asynSuccess; }
int main (int argc, char *argv[]){ /*int c; FILE *pp; extern FILE *popen(); if ( !(pp=popen("ls -l", "r")) ) return 1; while ( (c=fgetc(pp)) != EOF ) { putc(c, stdout); fflush(pp); } pclose(pp);*/ //пользовательскике данные struct UserParams userParams; Dict login = DictCreate(); Dict fLogin = DictCreate(); Dict location = DictCreate();; userParams.login = login; userParams.fLogin = fLogin; userParams.location = location; //параметры адреса printf("starting server\n"); struct addrinfo hints; memset(&hints, 0, sizeof hints); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; // получаение списка доступных адресов char* port = "8080"; struct addrinfo* addresses = getAvilableAddresses(&hints, port); if(!addresses) return EXIT_FAILURE; //коннект сокета int socketfd = assignSocket(addresses); if(!socketfd) return EXIT_FAILURE; if (setNonBlock(socketfd) == -1){ perror("non_block"); return EXIT_FAILURE; } if (listen (socketfd, SOMAXCONN) == -1){ perror ("listen"); return EXIT_FAILURE; } printf("listening port %s\n", port); //создание epoll int epollfd = epoll_create1(0); if (epollfd == -1){ perror ("epoll_create"); return EXIT_FAILURE; } if (addToEpoll(epollfd, socketfd) == -1) return EXIT_FAILURE; //регистрация обработчика событий signal(SIGINT, handleSignal); int maxEventNum = 8; struct epoll_event events[maxEventNum * sizeof(struct epoll_event)]; //заполнение параметров для потоков struct Params params; pthread_mutex_init(¶ms.mutex, NULL); pthread_cond_init(¶ms.condvar, NULL); params.end = 0; params.currrent = 0; params.epollfd = epollfd; params.events = events; params.socketfd = socketfd; params.userParams = userParams; pthread_t working[WORKING_THREADS_COUNT]; for(int i = 0; i<WORKING_THREADS_COUNT; i++){ pthread_create(&working[i], NULL, workThread, ¶ms); } //обработка событий int timeout = -1 ; while(!done){ if(params.currrent >= params.end){ printf("waiting new events\n"); int eventsNumber = epoll_wait(epollfd, events, maxEventNum, timeout); params.currrent = 0; params.end = eventsNumber; printf("Send\n"); pthread_cond_signal(¶ms.condvar); } } printf("server is going down\n"); printf("closing connections\n"); close(socketfd); close(epollfd); printf("done\n"); return EXIT_SUCCESS; }
bool CWSAThread::doListen() { bool bret = false; sockaddr_in serv_addr; m_listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); do { if (m_listenfd == INVALID_SOCKET) { LOG(_ERROR_, "CWSAThread::doListen() error, create listen socket failed"); break; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(m_serverport); if (m_serverip.empty()) { serv_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); } else { serv_addr.sin_addr.S_un.S_addr = fgAtoN(m_serverip.c_str()); } int tmp = 1; if (setsockopt(m_listenfd, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, sizeof(tmp)) == SOCKET_ERROR) { LOG(_ERROR_, "CWSAThread::doListen() error, setsockopt() failed, listen fd=%d, error=%ld", m_listenfd, WSAGetLastError()); break; } if (!setNonBlock(m_listenfd)) { LOG(_ERROR_, "CWSAThread::doListen() error, setNonBlock() failed, listen fd=%d", m_listenfd); break; } if (bind(m_listenfd, (sockaddr*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR) { LOG(_ERROR_, "CWSAThread::doListen() error, bind() failed, listen fd=%d, error=%ld", m_listenfd, WSAGetLastError()); break; } if (listen(m_listenfd, 4096) == SOCKET_ERROR) { LOG(_ERROR_, "CWSAThread::doListen() error, listen() failed, listen fd=%d, error=%ld", m_listenfd, WSAGetLastError()); break; } m_listenkey = new SOCKET_KEY; if (!m_listenkey) { LOG(_ERROR_, "CWSAThread::doListen() error, _new SOCKET_KEY failed, listen fd=%d", m_listenfd); closesocket(m_listenfd); m_listenfd = INVALID_SOCKET; exit(-1); } m_listenkey->fd = m_listenfd; m_listenkey->connect_time = getIndex(); WSAEVENT event = ::WSACreateEvent(); if (event == WSA_INVALID_EVENT) { LOG(_ERROR_, "CWSAThread::doListen() error, _new SOCKET_KEY failed, listen fd=%d", m_listenfd); break; } //TODO check here, if we need set FD_CONNECT, FD_CLOSE event if (::WSAEventSelect(m_listenfd, event, FD_ACCEPT | FD_READ | FD_CONNECT | FD_CLOSE) == SOCKET_ERROR) { LOG(_ERROR_, "CWSAThread::doListen() error, WSAEventSelect() failed, listen fd=%d, error=%ld", m_listenfd, WSAGetLastError()); break; } m_eventArray[m_nEventTotal] = event; m_sockArray[m_nEventTotal] = m_listenfd; m_keymap[m_nEventTotal] = m_listenkey; m_nEventTotal++; LOG(_INFO_, "CWSAThread::doListen() successed, listen fd=%d, m_nEventTotal=%d", m_listenfd, m_nEventTotal); bret = true; } while(false); return bret; }