/* Created by: Giorgos Kappes */ /* Year of first version: 2008 */ /* For any question mail to: g_kappes@hotmail.com */ /* This is open source software */ /****************************************************************/ /* Compile: gcc tcpconnect.c -o tcpconnect */ /****************************************************************/ #include /* perror() and errno */ #include /* required by getprotobyname() */ #include #include /* both required by socket() */ #include /* define sockaddr_in */ #include /* memset() */ #include #include #include #define MESSAGE_LEN 4096 /* Sent message Length */ #define BUFFER_SIZE 4096 /* Store buffer's size */ #define TIMEOUT_TIME 10 /* Timeout time */ #define TIMEOUTS 5 /* Number of timeouts */ extern int errno; extern int h_errno; void PrintHelp() { printf("-------------------------------------------------------------\n"); printf(" TCPCONNECT VERSION: 1.0\n"); printf("-------------------------------------------------------------\n"); printf("Created by: Giorgos Kappes\n"); printf("Year of first version: 2008\n"); printf("For any question mail to: g_kappes@hotmail.com\n"); printf("This is open source software\n"); printf("-------------------------------------------------------------\n"); printf(" SOME HELP\n"); printf("-------------------------------------------------------------\n"); printf("SYNTAX\n--> tcpconnect [host name/ ip address] [port number] \n"); printf("EXAMPLES\ntcpconnect 85.167.12.10 21\n"); printf("tcpconnect scylla.cs.uoi.gr 80\n"); printf("-------------------------------------------------------------\n"); } main(int argc, char *argv[]) { /* VARIABLES */ int sd; /* our socket descriptor */ int rval; /* our connect descriptor */ int port; /* the connection port */ char *message; /* the message to send */ char buffer[BUFFER_SIZE]; /* the store bufer needed by recv */ int bytes; /* the received bytes */ int ans = 1; /* the user's choice */ FILE *in; /* file descriptor */ char file[32]; /* the filname */ int timeouts = 0; /* the timeouts */ struct timeval tv; /* setting timemr for timeout check */ tv.tv_sec = TIMEOUT_TIME; tv.tv_usec=0; /* Strucrure to store pointer to protocol name in /etc/protocol*/ struct protoent *protocol; /* structure to store ip address and port for connection */ struct sockaddr_in socketaddr; /* structure to setup the address of the remote host */ struct hostent *hostaddr; /* ----------------------------------------------------------- */ /* CHECK PROGRAM RUN */ /* Check The arguments */ if (argc<2) { /* No arguments given. We must print program */ PrintHelp(); /* information */ exit(0); } else if (argc<3) { printf("ERROR - Missing argument.\n"); exit(0); } else if (argc>3) { printf("ERROR - Too much arguments.\n"); exit(0); } /* Get the specified port */ port = atoi(argv[2]); /* ----------------------------------------------------------- */ /* INITIALIZE PROTOCOL - SOCKET AND CONNECT */ /* initialize the protocol pointer by calling getprotobyname */ protocol = getprotobyname( "tcp" ); if ( !protocol ) { perror( "getprotobyname()" ); return (errno); } /* build our socket * * The socket descriptor 'sd' is a unique number that we will use* * later to refer to the socket. Specifically, it is needed to * * read and write data with our new socket. */ sd = socket( PF_INET, SOCK_STREAM, protocol->p_proto ); if ( sd == -1 ) { perror( "socket()" ); return (errno); } /* Set timeout option to recv. */ if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv)) { perror("setsockopt"); return -1; } /* At this point, all we have done is created a means for * * communicating on the network, but we are not connected to * * anyone at this point. Before we can do that, we must decide * * who it is we want to talk to and establish a connection. */ /* BSD, Unix, Linux, and the other members of the POSIX family * * give us a convenient method to connect to a remote host: * * int connect(int sockfd, const struct sockaddr *serv_addr, * * socklen_t addrlen); * * ------------------------------------------------------------- * * sockfd: descriptor of the socket we created * * struct sockaddr: tells connect() who it is that we want to * * talk to. we're going to use the sockaddr_in * * struct and use a cast to make it work with * * connect(). sockaddr_in is basically sockaddr * * with a spot for a port number and an Internet* * address, both of which we'll need with TCP/IP* * addrlen: the length of the address */ /* Initialize socketaddr */ memset( &socketaddr, 0, sizeof(socketaddr)); /* initialize it */ socketaddr.sin_family = AF_INET; /* set the fam type to Internet */ socketaddr.sin_port = htons( port ); /* set port to argv[2] */ /* Now we need to setup the address of the remote host. This * * will be done with the function: * * struct hostent *gethostbyname(const char *name); * * ------------------------------------------------------------- * * The argument of gethostbyname() may either be a recognized * * hostname, or it may be the IP address in numbers-and-dot * * notation. Either way, the address of a hostent structure is * * returned. */ hostaddr = gethostbyname(argv[1]); if ( !hostaddr ) { fprintf( stderr, "gethostbyname(): %s\n", hstrerror(h_errno) ); return (h_errno); } /* Now we'll use memcpy() to place it in our sockaddr_in struct: */ memcpy( &socketaddr.sin_addr, hostaddr->h_addr, hostaddr->h_length ); /* At this point, we're ready to connect to the remote host: */ rval = connect( sd, (struct sockaddr *) &socketaddr, sizeof(socketaddr) ); if ( rval == -1 ) { perror( "connect()" ); return (errno); } /* If the call to connect() succeeds, we have established a * * session to the remote host. */ printf("\nConnection with %s on port %d established!\n\a",argv[1],port); /* -------------------------------------------------------------- */ /* READING AND WRITTING * * -------------------- * * send() and recv() are used to send and receive data over a * * connection, respectively * * int send(int s, const void *msg, size_t len, int flags); * * int recv(int s, void *buf, size_t len, int flags); * * -------------------------------------------------------------- * * --> Both functions are remarkebly similar. In both cases, the * * first argument is our socket descriptor, and the last argument * * is the place to set flags that modify default behavior (flags * * will normally be set to NULL, indicating we would like to * * with the defaults). * * --> For send(), the second argument is a pointer to the data * * to transmit, and the third argument is the number of bytes to * * send. For recv(), the second argument is a pointer to the * * buffer to store incoming data, and the third argument is the * * number of bytes that can be safely stored without overflowing * * the buffer. * * --> Both functions return the number of bytes processed * * (number sent or received, depending on which function you * * called), or -1 in the event of an error. * * --> By default, the recv() function is blocking. This means * * that if there is no data waiting to be read on the socket, * * recv() will wait until something comes in or until the * * connection is lost */ /* Initialize the message buffer */ message = (char *)malloc(MESSAGE_LEN*sizeof(char)); if ( message == NULL ) { perror( "malloc()" ); return (errno); } while (ans != 3) { printf("\n1. Send a message\n2. Try to Receive\n3. Close connection\n\n> "); scanf("%d",&ans); while (ans < 1 || ans > 3) { printf("Command not recognised. Please type 1 or 2 or 3\n"); printf("1. Send a message\n2. Try to Receive\n3. Close connection\n\n> "); scanf("%d",&ans); } if (ans == 1) { printf("Now you must specify the file which conatins you message\n"); printf("Please enter the filename or path: "); scanf("%s",file); in = fopen(file,"r"); if ( in == NULL ) { perror( "fopen()" ); } else { fgets(message,4096,in); fclose(in); bytes = send(sd, message, strlen(message), 0); if ( bytes == -1 ) { perror( "send()" ); return (errno); } else printf("\nMessage sent!\n\n"); } } else if (ans == 2) { while(1) { printf("Receiving. . .\n"); bytes = recv(sd, buffer, sizeof(buffer),0); if ( bytes == -1 ) { perror( "recv()" ); /* if a timeout happend receive again until timeout limit */ if (errno == 29 && timeouts