GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 21-Jan-2007, 15:41
EricTWiggins EricTWiggins is offline
New Member
 
Join Date: Jan 2007
Posts: 5
EricTWiggins is on a distinguished road

Learning TCP/IP aka TELNET programming but...


I am trying to run a server code that will send a simple message to a client once it connects and allow the client to send a string of text to the server and have the server to disply that. The soul reason is to learn about TCP/IP programming WINSOCK and WINSOCK2. I have been pounding the keyboard for a few weeks now and doing online learning from the few places that break it down to a low, no joke its dum simple, code.

Well... my code wont send a string accross the net... 127.0.0.1 3000. The code is as follows:

CPP / C++ / C Code:
//COMPILED WITH BLOODSHEAD DEVCPP

#include <winsock2.h> //This is the newest/greatest winsock... I think...
#include <winsock.h>  //Do I really need this and winsock2?? 
#include <iostream> //Basic knowlege stuff...
#include <cstring> //string stuff..

//TCP_IP VALUES
int PORT=3000;
char ADDRESS[]="127.0.0.1"; //just informational not used in the code.
char recvbuffer[1000];
using namespace std;
main()
{

WSADATA ws;   //got to have because windows 
WSAStartup(0x0101,&ws); //same... 

SOCKET tcp_socket;  //Making my socket now
struct sockaddr_in peer; //incomming IP??? 
int peerlen;//just an everyday int var..

fd_set fd; //create a file descriptor set called fd
FD_ZERO(&fd); //zero out our fd (otherwise this program tends to crash)
struct timeval tv; //create a time value object
tv.tv_sec = 3; //set our timer value to wait for 3 seconds
tv.tv_usec = 0;

peer.sin_family = AF_INET; //ok you got AF_ and AP_??? what's that about
peer.sin_port = htons(PORT); //My port of 3000
peer.sin_addr.s_addr = htonl(INADDR_ANY); // let anything connect...

tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
 //_STREAM TCP/IP.. and DTGRAM for UDP/IP... I think.. Got the UDP to work with text only for LAN connections.. need/want TELNET.

bind(tcp_socket,(struct sockaddr *)&peer,sizeof(peer));//Got it, understand it
listen(tcp_socket,3);//Got it, Understand it.

tv.tv_sec=0;
select(1, &fd, NULL, NULL, &tv);
tv.tv_sec=3;

while(1){ 
//ENTERED INTO AN INF LOOP... CTRL+C to close server

//FD RESET TO MAKE SELECT WORK
        FD_SET(tcp_socket, &fd); //re-set the fd so select() will work
        select(1, &fd, NULL, NULL, &tv);

while (!FD_ISSET(tcp_socket, &fd)) //if socket hasn't received any data yet...
        {
        FD_SET(tcp_socket, &fd); //re-set the fd so select() will work
        select(1, &fd, NULL, NULL, &tv);
        if (!FD_ISSET(tcp_socket, &fd)) {cout<<"Still waiting for data...\n";}
        }
//SOMETHIGNN IS MISSING>>> WILL NOT SEND NOR RECV MESSAGES ..... 

recv(tcp_socket,recvbuffer,sizeof(recvbuffer),0);
cout<<"RECVBUFFER:"<<recvbuffer<<endl;
send(tcp_socket,"TEST MESSAGE",12,0);
peerlen=sizeof(peer);
accept(tcp_socket,(struct sockaddr *)&peer, &peerlen);

}

//system("PAUSE");
//CLEAN UP THE SOCKETS
closesocket(tcp_socket);
shutdown(tcp_socket,0);
return(0);
}

I am not getting this to send or recieve messages at all. On command prompt it just sticks with connecting to... The source code came from http://www.geocities.com/siliconvalley/2072/sockprog.htm with slight mods made by myself. ... If anyone could help me get the joker chating, a thousand blessings and thanks. Please be extreamly basic in CPP terms. I know just enough to get myself into trouble.
Last edited by LuciWiz : 22-Jan-2007 at 01:40. Reason: Please insert your C/C++ code between [cpp] & [/cpp] tags
  #2  
Old 22-Jan-2007, 11:34
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 6,153
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Learning TCP/IP aka TELNET programming but...


Quote:
Originally Posted by EricTWiggins
I am trying to run a server code that will send a simple message to a client once it connects and allow the client to send a string of text to the server and have the server to disply that. The soul reason is to learn about TCP/IP programming WINSOCK and WINSOCK2.

Have you looked at beej's really (really) excellent web site? http://beej.us/guide

I wouldn't dream of trying to learn any network programming without downloading and printing this: http://beej.us/guide/bgnet/output/print/bgnet.pdf

In section 6.2: "This program acts like a simple multiuser chat server. Start it running in one window, then telnet to it (“telnet hostname 9034”) from multiple other windows. When you type something in one telnet session, it should appear in all the others."

The source for this is "selectserver.c" in this directory: http://beej.us/guide/bgnet/examples/

Depending on what Windows compiler you are using, you just delete the UNIX/Linux headers and put in the <winsock2.h> and the WSA startup stuff.

Here's the way I modified the beginning of the file. If I comment out the #define WINDOWS statement, it's the same as beej's original (so I can compile/execute on Linux). The particular changes that I made enable me to compile and execute on my Windows XP platform with various Borland and Microsoft compilers.

CPP / C++ / C Code:
/*
** selectserver.c -- a cheezy multiperson chat server
* First part modified by davekw7x
* Borland: just compile with bcc32
* Microsoft: Make sure library wsock32.lib is in the project
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define WINDOWS

#ifdef WINDOWS
#include <winsock2.h>

typedef unsigned int socklen_t;
#else

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

#define PORT 9034               // port we're listening on

int main(void)
{
    fd_set master;              // master file descriptor list
    fd_set read_fds;            // temp file descriptor list for select()
    struct sockaddr_in myaddr;  // server address
    struct sockaddr_in remoteaddr;      // client address
    int fdmax;                  // maximum file descriptor number
    unsigned listener;               // listening socket descriptor
    int newfd;                  // newly accept()ed socket descriptor
    char buf[256];              // buffer for client data
    int nbytes;
    char yes = 1;                // for setsockopt() SO_REUSEADDR, below
    socklen_t addrlen;
    int i, j;
#ifdef WINDOWS
    WSADATA ws;   //got to have because windows 
    WSAStartup(0x0101,&ws); //same... 
#endif


If you have already compiled other Windows socket stuff with your compiler, you know whether you have to do something special to link in the wsock2.lib library. (Borland compilers that I use don't require anything extra, Microsoft compilers do.)

One reason that your simple UDP server won't work with telnet clients is that telnet protocol involves two ports: Initially connection is made through whatever port the server is listening on. Various telnet-specific control information is transported on this port. Then the server opens a new port for data (the telnet protocol gets this information back to the client) and the telnet client opens a new port according to the server's instructions on the control port. Then all data transfer is through this new data port. (There may be other problems with your program, but I haven't tried to straighten it out --- beej's example works for me, and I like the narrative.)

If additional telnet clients try to hook up, the server gives each one a port number for that client's data.

SO: The clients do not talk to each other through the original telnet server port; each talks to the server through that client's data port and this particular server sends data from any client port to all of the other clients that are connected.

Regards,

Dave


Footnotes:
1. It's a C program. If you want C++, no changes are required. You can put cout<< instead of printf(), and, eventually, you can make a C++ class to handle socket I/O (using C++ strings instead of arrays of chars; stuff like that). But if your main goal is to learn TCP/IP and Telnet stuff, you can just leave the code looking like C.

2. If you want to use the beej server program "selectserver" and you want to send a "Welcome" message to each new client as it obtains a connection, then find the place in the source where it reports the new connection on the server console, and put something to send the message. Something like:

CPP / C++ / C Code:
        printf("selectserver: new connection from %s on socket %d\n",
                inet_ntoa(remoteaddr.sin_addr), newfd);
        if(send(newfd, "Welcome!\r\n", strlen("Welcome!\r\n"), 0) == -1) {
            perror("send");
            printf("Error sending welcoming message\n");
        }

3. If you want the telnet server to display text from each client as it is received:... (Well, I have to leave something for you to do, right?)

4. If you only want one client to talk to one server, then you don't need telnet. Look at beej's earlier examples of client and server UDP programs. But I see you said that you had already mastered UDP. I think that it still won't hurt to go through beej's examples.

5. The word "cheezy" in the comment is from beej, not me. Since it works as intended and it serves the purpose of illustrating a number of very practical points, I would never call it "cheezy"!

6. Since the title of thread is about "telnet", I am assuming that you are using a telnet client to talk to this server. If you are using something else, let us know what it is. The example from beej works with telnet clients that were installed by default on my Windows systems and my Linux systems as well as with various telnet test programs that I have tried.
Last edited by davekw7x : 22-Jan-2007 at 12:31.
  #3  
Old 22-Jan-2007, 15:53
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 6,153
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Learning TCP/IP aka TELNET programming but...


Quote:
Originally Posted by davekw7x
One reason that your simple UDP server won't work with telnet clients is that telnet protocol involves two ports:
I got the explanation screwed up here, and you should replace that entire paragraph with this:

Each client contacts the server with packets having a destination address consisting of the IP address and whatever port number on which the server is listening. ("Normal" telnet service is on server port 23; our special test server can use any port not specifically being reserved for other services; usually a high number. This is coded into the server application, and the clients must know what server port to use.)

On any given machine a client program is granted a unique socket fd for each request. Part of that socket's data information is the destination IP address and port number. The packets through a given socket from each client, therefore, have a unique ip address and a port number as their source address and the telnet server and port number as destination address. Packets from server to a client uses that client's destination IP address and port number.

For each new connection, the accept function in the server gets a new fd (a new socket connection) that it uses for data transfer to and from a particular client. Part of the socket's data information is the client IP address and port number, and this is how the server keeps traffic separate for the various clients. There is no separate "control" port from the client's point of view.

I recently worked on some ftp problems and that is what was in the almost-remembered/almost-forgotten area of my short/medium term memory and I just got things jumbled up. Kind of like Winnie the Poo's spelling. (See footnote.) With ftp, there are actually separate connections that are negotiated between client and server: a "control" connection that remains constant for the duration of the session, and a separate "data" connection that is negotiated and established for each data transfer. It's more complicated than simple TCP/telnet connection.

I regret the error, and I reiterate my exhortation that you should never get all of your information from one source. Don't take my word for it (or any other one person's) as absolute.

Regards,

Dave


Footnote:
"My spelling is wobbly. It's good spelling, but it wobbles, and the letters get in the wrong places."
---A. A. Milne
"Winnie the Pooh"

"Kind of like my telnet explanation: A little wobbly. The words were good words, but some of them just got in the wrong places."
---davekw7x
  #4  
Old 24-Jan-2007, 05:33
EricTWiggins EricTWiggins is offline
New Member
 
Join Date: Jan 2007
Posts: 5
EricTWiggins is on a distinguished road

Re: Learning TCP/IP aka TELNET programming but...


Hey everyone!, I just wanted to say thanks for the help. After many more study hours and about 5am, I was able to compile my first Telnet session with wounderful results. Beej is the best! I once before found that site but wrongfully click off to another because in the body he stated the info was written for linux/unix and he/she had a major dislike of windows.... tisk tisk, I should have kept reading onward anyway.

Well, I have now moved to NON-Blocking/multi-threading. WOW!! so much at one time! Well thats ok too... I'll hack and slash my way through the source, code examples, and gobs of website till I get it figured out.

Here is the source code I now have, if anyone else comes along needing an expamle with comments.

Compiled with BLOODSHEAD DEVCPP
SETUP: PROJECT OPTIONS, LINKER, link to ../lib/libwsock32.a and ../lib/libws2_32.a
TESTED USING: zMUD, telnet client for MUDs, and windows 2000 TelNet.
Source follows:


CPP / C++ / C Code:
#include <winsock2.h> //required for socket programming, has winsock.h and more 
#include <iostream> //standard input output
#include <cstring> //allows user to work with and mod strings
#include <fstream> //allows user to work with files

//SERVER VALUES FOR IOFILES
int intro();     //declare a global sub 
//TCP_IP VALUES
int sockfd,new_fd;   //global declare int of xyz
int PORT=3000;    // global declare my port, also makes it easy to edit being at the top
int BACKLOG=10;   // Max allowed connections to the server
char ADDRESS[]="127.0.0.1"; //just for general info, could place it in the spot of INADDY_ANY..but why? That would only allow connections on that IP
char buffer[1000];  //Global declare of buffer to send/recv on and do whatever else we say.
char *msg; //Global declare "WILD" var. Flexable var with no set size.  use sizeof(msg) if size needed
int len; //Did I use this???? 

using namespace std;  //Standard for all PGMs. See your help files. 
main()  //MAIN ROUTINE
{
//heading information displayed on the server screen
cout<<"The TEST SERVER OF LEARNING"<<endl<<"Press CTRL+C to exit server."<<endl;
WSADATA ws;   //Windows required for winsock
WSAStartup(0x0101,&ws);  //Windows required for winsock.


//from here forward uncommented code is considered to be understood.

fd_set fd; //create a file descriptor set called fd
FD_ZERO(&fd); //zero out our fd (otherwise this program tends to crash)
struct timeval tv; //create a time value object
tv.tv_sec = 3;   //set the timeval struct seconds
tv.tv_usec = 0;
select(1, &fd, NULL, NULL, &tv); //Setting up our select to allow more than one connection

struct sockaddr_in my_addr;  //Building the socket names
struct sockaddr_in their_addr;
int sin_size; //just a plain int var to be used leater, at this time in code. It has no value.

sockfd=socket(PF_INET, SOCK_STREAM, 0); //Build our socket

my_addr.sin_family = AF_INET; //
my_addr.sin_port = htons(PORT); //HOST TO NETWORK SHORT -->setup SERVER port number
my_addr.sin_addr.s_addr=INADDR_ANY; //Setup SERVER to take any IP
memset(&(my_addr.sin_zero), '\0',8 ); //Fill in the remaining blank segments with 0

bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr)); //The binding of SERVER IP to the NET
listen(sockfd, BACKLOG); //COMPUTER IS NOW SET TO LOOK/LISSEN for other computers to connect
while(1){  //jumping into a perm. LOOP, yea it will never end.
         while(!FD_ISSET(sockfd,&fd)){ //No one is wanting to connect??? also this is called NON-BLOCKING
           FD_SET(sockfd, &fd); //re-set the fd so select() will work
           select(1, &fd, NULL, NULL, &tv);
           sin_size = sizeof(struct sockaddr_in); //We got a hit and now setting up SOCKET size
           //new_fd is the return path to talk to the calling computer. However!!!, when in a non
           //non-blocking program, I yet to understand how to recv info into the server. 
           new_fd=accept(sockfd,(struct sockaddr *)&their_addr, &sin_size); 
           intro(); //call the sub rout. to send a file or into screen to the calling computer
           }
  recv(new_fd,buffer,sizeof(buffer),0); //not working yet... I am still learning.
  cout<<buffer; //used to see what the server recv'ed
  //send(new_fd,buffer,sizeof(buffer),0);//send something back to the client.. uncomment to activate
}

//system("PAUSE"); //make the SERVER pause before exiting, wused when debugging
WSACleanup(); //Cleanup the winsock
closesocket(sockfd); //close down the SERVER sockets
shutdown(sockfd,0); 
return(0);
}

int intro() //sub rout for learning how to send a file to the user screen
{
ifstream ifstartup ("startup.are" , ifstream::in ); //seeing if i can send a file to the screen
while(ifstartup.good()){
ifstartup.getline(buffer, sizeof(buffer));
strcat(buffer, "\n"); //force new line, other wise it jumbles up
send(new_fd,buffer,sizeof(buffer),0);
};
msg="\n\nWelcome to this test server.\n";
len=strlen(msg);
send(new_fd,msg,len,0);
ifstartup.close();
}

The only issue with the code now is that in the WHILE(1) loop the server does not display what the client has typed. However, the server does send data to the different clients. I would have used WHILE(strcmp(buffer, "svrEXIT")!=0) to controll this but then buffer never got the string data... or so it seems. Thus, its still and infinity loop either way.

HEY, If you got any comments on my coding style or the posted source, PLEASE be critical. I need to learn good programming habits. Also, If you know any good books I could buy about TCP/IP and/or UDP/IP programming, let me know about that too.

Thank again everyone for reading/helping.
Last edited by admin : 25-Jan-2007 at 08:58. Reason: Please insert your C code between [cpp] & [/cpp] tags
  #5  
Old 25-Jan-2007, 05:01
davis
 
Posts: n/a

Re: Learning TCP/IP aka TELNET programming but...


Quote:
Originally Posted by EricTWiggins
HEY, If you got any comments on my coding style or the posted source, PLEASE be critical.

...how about good forum posting habits first? In other words, put your code in between [c] ... [/c] tags! ..then maybe we can at least read it?

Read the www.gidforums.com for more details.

It seems as if you're having a good time discovering network programming. It is a lot of fun. Now you need to get rid of Windoze and start using a real programmer's operating system!


:davis:
  #6  
Old 25-Jan-2007, 08:18
EricTWiggins EricTWiggins is offline
New Member
 
Join Date: Jan 2007
Posts: 5
EricTWiggins is on a distinguished road

Re: Learning TCP/IP aka TELNET programming but...


ah, thanks! The first post did it for me.. I was woundering how to make it "set off from the rest of the message body when it wasn't doing right. I'll be sure to use the blocking tags from now on.
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Looking for opinions crystalattice Miscellaneous Programming Forum 6 27-Sep-2006 21:02
printer / font color / windows programming nicolas_qc MS Visual C++ / MFC Forum 0 03-Jan-2006 23:13
which language ? onauc C++ Forum 2 19-Nov-2004 02:53
GUI programming crystalattice C++ Forum 5 14-Sep-2004 12:17

Network Sites: GIDNetwork · GIDApp · GIDBlog · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 20:40.


vBulletin, Copyright © 2000 - 2014, Jelsoft Enterprises Ltd.