/* minazuki3.c - Don Yang (uguu.org) 07/04/02 */ #ifdef _WIN32 #include #include typedef SOCKET s; DWORD wthread; #define c closesocket #else #include #include #include #include #include #include #include #include #include #include #include typedef int s; pthread_t wthread; #define c close #endif #include #include #include static int writer_active, size; static s sock, s2; static struct sockaddr_in a1, a2; static fd_set sset, rset; static struct hostent *hostinfo; static unsigned short port = 0; static char readbuffer[1025], writebuffer[1025]; struct timeval timeout; static void createsocket(void) { sock = socket(PF_INET, SOCK_STREAM, 0); a2.sin_family = AF_INET; a2.sin_port = htons(port); a2.sin_addr.s_addr = htonl(INADDR_ANY); if( bind(sock, (struct sockaddr*)&a2, sizeof(struct sockaddr_in)) == -1 ) { puts("bind"); sock = -1; return; } } #ifdef _WIN32 static DWORD WINAPI write_loop(void *arg) #else static void *write_loop(void *arg) #endif { writebuffer[1024] = '\0'; while( writer_active ) { printf("> "); fgets(writebuffer, 1024, stdin); if( feof(stdin) ) break; send(sock, writebuffer, strlen(writebuffer), 0); } writer_active = 0; return 0; } int main(int argc, char **argv) { #ifdef _WIN32 WSADATA wsadata; if( WSAStartup(2, &wsadata) ) return puts("WSAStartup"); #endif if( argc < 3 ) return printf("%s \n", *argv); if( (hostinfo = gethostbyname(argv[1])) == NULL ) { if( (a1.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE ) return puts("inet_addr"); } else { a1.sin_addr = *(struct in_addr*)hostinfo->h_addr; } createsocket(); if( sock == -1 ) return 1; a1.sin_family = AF_INET; a1.sin_port = htons(port = (unsigned short)atoi(argv[2])); if( connect(sock, (struct sockaddr*)&a1, sizeof(struct sockaddr_in)) == -1 ) { c(sock); createsocket(); if( sock == -1 ) return 1; if( listen(sock, 1) == -1 ) { c(sock); return puts("listen"); } FD_ZERO(&sset); FD_SET(sock, &sset); select(FD_SETSIZE, &sset, NULL, NULL, NULL); size = sizeof(struct sockaddr_in); s2 = accept(sock, (struct sockaddr*)&a1, &size); c(sock); if( s2 == -1 ) return puts("accept"); size = sizeof(struct sockaddr_in); getpeername(s2, (struct sockaddr*)&a1, &size); sock = s2; } printf("Connected to %s:%hd\n", inet_ntoa(a1.sin_addr), ntohs(a1.sin_port)); writer_active = 1; #ifdef _WIN32 CreateThread(NULL, 0, write_loop, NULL, 0, &wthread); #else pthread_create(&wthread, NULL, write_loop, NULL); #endif FD_ZERO(&sset); FD_SET(sock, &sset); while( writer_active ) { memcpy(&rset, &sset, sizeof(fd_set)); timeout.tv_sec = 1; timeout.tv_usec = 0; select(FD_SETSIZE, &rset, NULL, NULL, &timeout); if( FD_ISSET(sock, &rset) ) { size = recv(sock, readbuffer, 1024, 0); if( size <= 0 ) { writer_active = 0; break; } readbuffer[size] = '\0'; printf("\r \r%s> ", readbuffer); fflush(stdout); } } shutdown(sock, 2); c(sock); putchar('\n'); #ifdef _WIN32 WSACleanup(); #endif return 0; }