Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   HEEELLLPPP socket programing instant messaging (http://www.velocityreviews.com/forums/t459849-heeelllppp-socket-programing-instant-messaging.html)

Sean 01-16-2007 01:54 AM

HEEELLLPPP socket programing instant messaging
 
Hi Everyone,
My apologies for a somewhat dump question but I am really stuck. I have
been working on this code for two days straight I am dont know what is
wrong with it. when I run the code, All I get is Input: and the program
quits. I also tried reading this online but I didn't quite get it.

What is the diff between sin_addr and sin_addr.s_addr. My understanding
is that the latter is the IP address of my machine where as the former
is the destination IP address.

Also why doesn't the program stop at
cout << "Input: ";
cin.get(buf, MAX_LINE, '\n');

for the user to enter something.

I am trying to write an instant messaging program (peer to peer).

Below is my code.

Thanks in advance


#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <iostream>
#include <arpa/inet.h>

#define MAX_LINE 100
#define LINE_ARRAY_SIZE (MAX_LINE+1)
#define PORT 15002

using namespace std;

int main()
{
int socketDescriptor;
struct sockaddr_in serverAddress;
char buf[LINE_ARRAY_SIZE], c;
struct hostent *hostInfo;

cout << "Enter IP address: ";
cin.get(buf, MAX_LINE, '\n');

socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
if (socketDescriptor < 0) {
cerr << "cannot create socket\n";
exit(1);
}

hostInfo = gethostbyname(buf);
if (hostInfo == NULL) {
cout << "problem interpreting host: " << buf << "\n";
exit(1);
}

memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(PORT);
inet_aton(buf, &(serverAddress.sin_addr));
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
if( bind(socketDescriptor, (struct sockaddr *) &serverAddress,
sizeof(serverAddress)) )
cerr << "bind() failed" ;

memset(buf, 0x0, LINE_ARRAY_SIZE);
cout << "Input: ";
cin.get(buf, MAX_LINE, '\n');
while (cin.get(c) && c != '\n')
;


// Send the line to the server.
if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) {
cerr << "cannot send data ";
close(socketDescriptor);
exit(1);
}

// Zero out the buffer.
memset(buf, 0x0, LINE_ARRAY_SIZE);

// Read the modified line back from the server.
if (recv(socketDescriptor, buf, MAX_LINE, 0) < 0) {
cerr << "didn't get response from server?";
close(socketDescriptor);
exit(1);
}

close(socketDescriptor);
return 0;
}


Alan Johnson 01-16-2007 04:18 AM

Re: HEEELLLPPP socket programing instant messaging
 
Sean wrote:
> Hi Everyone,
> My apologies for a somewhat dump question but I am really stuck. I have
> been working on this code for two days straight I am dont know what is
> wrong with it. when I run the code, All I get is Input: and the program
> quits. I also tried reading this online but I didn't quite get it.
>
> What is the diff between sin_addr and sin_addr.s_addr. My understanding
> is that the latter is the IP address of my machine where as the former
> is the destination IP address.
>
> Also why doesn't the program stop at
> cout << "Input: ";
> cin.get(buf, MAX_LINE, '\n');
>
> for the user to enter something.
>
> I am trying to write an instant messaging program (peer to peer).
>
> Below is my code.
>
> Thanks in advance


[irrelevant code removed]

> cout << "Enter IP address: ";
> cin.get(buf, MAX_LINE, '\n');


> cout << "Input: ";
> cin.get(buf, MAX_LINE, '\n');


The get() method does not remove the delimiter from the stream. So,
let's say you type "192.168.1.1\n" when prompted for the IP address.
The "192.168.1.1" is removed from the stream, but "\n" is left in there.
Now, when you do the second get(), it immediately encounters your
delimiter and returns a zero length string.

Instead of using get(), use getline(). As in:
cin.getline(buf, MAX_LINE) ;

Or better yet, skip the whole MAX_LINE nonsense, and use std::string.

#include <string>
// ...
std::string ip_address;
std::getline(std::cin, ip_address);

Use the c_str() method when you need to access it as a c-style string.


--
Alan Johnson

bjeremy 01-16-2007 04:31 AM

Re: HEEELLLPPP socket programing instant messaging
 

Sean wrote:
> Hi Everyone,
> My apologies for a somewhat dump question but I am really stuck. I have
> been working on this code for two days straight I am dont know what is
> wrong with it. when I run the code, All I get is Input: and the program
> quits. I also tried reading this online but I didn't quite get it.
>
> What is the diff between sin_addr and sin_addr.s_addr. My understanding
> is that the latter is the IP address of my machine where as the former
> is the destination IP address.
>
> Also why doesn't the program stop at
> cout << "Input: ";
> cin.get(buf, MAX_LINE, '\n');
>
> for the user to enter something.
>
> I am trying to write an instant messaging program (peer to peer).
>
> Below is my code.
>
> Thanks in advance
>
>
> #include <netdb.h>
> #include <netinet/in.h>
> #include <unistd.h>
> #include <iostream>
> #include <arpa/inet.h>
>
> #define MAX_LINE 100
> #define LINE_ARRAY_SIZE (MAX_LINE+1)
> #define PORT 15002
>
> using namespace std;
>
> int main()
> {
> int socketDescriptor;
> struct sockaddr_in serverAddress;
> char buf[LINE_ARRAY_SIZE], c;
> struct hostent *hostInfo;
>
> cout << "Enter IP address: ";
> cin.get(buf, MAX_LINE, '\n');
>
> socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
> if (socketDescriptor < 0) {
> cerr << "cannot create socket\n";
> exit(1);
> }
>
> hostInfo = gethostbyname(buf);
> if (hostInfo == NULL) {
> cout << "problem interpreting host: " << buf << "\n";
> exit(1);
> }
>
> memset(&serverAddress, 0, sizeof(serverAddress));
> serverAddress.sin_family = AF_INET;
> serverAddress.sin_port = htons(PORT);
> inet_aton(buf, &(serverAddress.sin_addr));
> serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
> if( bind(socketDescriptor, (struct sockaddr *) &serverAddress,
> sizeof(serverAddress)) )
> cerr << "bind() failed" ;
>
> memset(buf, 0x0, LINE_ARRAY_SIZE);
> cout << "Input: ";
> cin.get(buf, MAX_LINE, '\n');
> while (cin.get(c) && c != '\n')
> ;
>
>
> // Send the line to the server.
> if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) {
> cerr << "cannot send data ";
> close(socketDescriptor);
> exit(1);
> }
>
> // Zero out the buffer.
> memset(buf, 0x0, LINE_ARRAY_SIZE);
>
> // Read the modified line back from the server.
> if (recv(socketDescriptor, buf, MAX_LINE, 0) < 0) {
> cerr << "didn't get response from server?";
> close(socketDescriptor);
> exit(1);
> }
>
> close(socketDescriptor);
> return 0;
> }


For your other question as to why your program doesn't stop at Input:.
The answer is that you previously issued a :

> cout << "Enter IP address: ";
> cin.get(buf, MAX_LINE, '\n');
>

but never cleared the "buf"... so there is still a line in your buffer
and it is exiting out... However, after you fix this (a few ways of
doing it, I'll leave it up to you to pick one), you will still have
some problems... so for you next question the difference between
sin_addr and s_addr can be confusing... but sin_addr is a member of the
struct sockaddr_in (internet socket address struct look in
netinet/in.h)... the member is of type in_addr. Struct in_addr has only
one member and that is s_addr... s_addr is a 32 bit IPv4 Address
supposedly in network byte order (big endian). This IP address can be
any IP Address and is not related to a local host or destination
address per se.

In your example I really can't tell if you are trying to open a client
socket or a server socket... Let's say you are trying to set up a
server socket, you bind to your local default IP Address, but after a
bind you should issue a listen() and then an accept() to await incoming
connections (if you use blocking i/o, which it looks like you do this
call will block).. Once you accept a client connection, then you could
send/recv data off that connection. But you will use the socket
descriptor of the new connection, not the descriptor you receved by
establishing your server socket

// Create socket for listening for client connection requests.
listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket < 0) {
cerr << "cannot create listen socket";
exit(1);
}

// Bind listen socket to listen port. First set various fields in
// the serverAddress structure, then call bind().
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(listenPort);

if (bind(listenSocket,
(struct sockaddr *) &serverAddress,
sizeof(serverAddress)) < 0) {
cerr << "cannot bind socket";
exit(1);
}

// Wait for connections from clients.
listen(listenSocket, 5);

while (1) {
cout << "Waiting for TCP connection on port " << listenPort << "
....\n";

// Accept a connection with a client that is requesting one.
clientAddressLength = sizeof(clientAddress);
connectSocket = accept(listenSocket,
(struct sockaddr *) &clientAddress,
&clientAddressLength);
if (connectSocket < 0) {
cerr << "cannot accept connection ";
exit(1);
}

//Read from the socket or whatever
while (recv(connectSocket, line, MAXMSG, 0) > 0) {
cout << line << "\n";
}

A client socket is somewhat different.. but there should be lots of
examples on the web on this...


Sean 01-16-2007 05:04 AM

Re: HEEELLLPPP socket programing instant messaging
 
Thanks for the rely. I am actually trying to make a program that is
both a client and a server. This means, that if you and I are both
running this code on our machines, I can make a call to you, in which
case, you will be the server and I will be the client and you can make
a call to me.


bjeremy wrote:
> Sean wrote:
> > Hi Everyone,
> > My apologies for a somewhat dump question but I am really stuck. I have
> > been working on this code for two days straight I am dont know what is
> > wrong with it. when I run the code, All I get is Input: and the program
> > quits. I also tried reading this online but I didn't quite get it.
> >
> > What is the diff between sin_addr and sin_addr.s_addr. My understanding
> > is that the latter is the IP address of my machine where as the former
> > is the destination IP address.
> >
> > Also why doesn't the program stop at
> > cout << "Input: ";
> > cin.get(buf, MAX_LINE, '\n');
> >
> > for the user to enter something.
> >
> > I am trying to write an instant messaging program (peer to peer).
> >
> > Below is my code.
> >
> > Thanks in advance
> >
> >
> > #include <netdb.h>
> > #include <netinet/in.h>
> > #include <unistd.h>
> > #include <iostream>
> > #include <arpa/inet.h>
> >
> > #define MAX_LINE 100
> > #define LINE_ARRAY_SIZE (MAX_LINE+1)
> > #define PORT 15002
> >
> > using namespace std;
> >
> > int main()
> > {
> > int socketDescriptor;
> > struct sockaddr_in serverAddress;
> > char buf[LINE_ARRAY_SIZE], c;
> > struct hostent *hostInfo;
> >
> > cout << "Enter IP address: ";
> > cin.get(buf, MAX_LINE, '\n');
> >
> > socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
> > if (socketDescriptor < 0) {
> > cerr << "cannot create socket\n";
> > exit(1);
> > }
> >
> > hostInfo = gethostbyname(buf);
> > if (hostInfo == NULL) {
> > cout << "problem interpreting host: " << buf << "\n";
> > exit(1);
> > }
> >
> > memset(&serverAddress, 0, sizeof(serverAddress));
> > serverAddress.sin_family = AF_INET;
> > serverAddress.sin_port = htons(PORT);
> > inet_aton(buf, &(serverAddress.sin_addr));
> > serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
> > if( bind(socketDescriptor, (struct sockaddr *) &serverAddress,
> > sizeof(serverAddress)) )
> > cerr << "bind() failed" ;
> >
> > memset(buf, 0x0, LINE_ARRAY_SIZE);
> > cout << "Input: ";
> > cin.get(buf, MAX_LINE, '\n');
> > while (cin.get(c) && c != '\n')
> > ;
> >
> >
> > // Send the line to the server.
> > if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) {
> > cerr << "cannot send data ";
> > close(socketDescriptor);
> > exit(1);
> > }
> >
> > // Zero out the buffer.
> > memset(buf, 0x0, LINE_ARRAY_SIZE);
> >
> > // Read the modified line back from the server.
> > if (recv(socketDescriptor, buf, MAX_LINE, 0) < 0) {
> > cerr << "didn't get response from server?";
> > close(socketDescriptor);
> > exit(1);
> > }
> >
> > close(socketDescriptor);
> > return 0;
> > }

>
> For your other question as to why your program doesn't stop at Input:.
> The answer is that you previously issued a :
>
> > cout << "Enter IP address: ";
> > cin.get(buf, MAX_LINE, '\n');
> >

> but never cleared the "buf"... so there is still a line in your buffer
> and it is exiting out... However, after you fix this (a few ways of
> doing it, I'll leave it up to you to pick one), you will still have
> some problems... so for you next question the difference between
> sin_addr and s_addr can be confusing... but sin_addr is a member of the
> struct sockaddr_in (internet socket address struct look in
> netinet/in.h)... the member is of type in_addr. Struct in_addr has only
> one member and that is s_addr... s_addr is a 32 bit IPv4 Address
> supposedly in network byte order (big endian). This IP address can be
> any IP Address and is not related to a local host or destination
> address per se.
>
> In your example I really can't tell if you are trying to open a client
> socket or a server socket... Let's say you are trying to set up a
> server socket, you bind to your local default IP Address, but after a
> bind you should issue a listen() and then an accept() to await incoming
> connections (if you use blocking i/o, which it looks like you do this
> call will block).. Once you accept a client connection, then you could
> send/recv data off that connection. But you will use the socket
> descriptor of the new connection, not the descriptor you receved by
> establishing your server socket
>
> // Create socket for listening for client connection requests.
> listenSocket = socket(AF_INET, SOCK_STREAM, 0);
> if (listenSocket < 0) {
> cerr << "cannot create listen socket";
> exit(1);
> }
>
> // Bind listen socket to listen port. First set various fields in
> // the serverAddress structure, then call bind().
> serverAddress.sin_family = AF_INET;
> serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
> serverAddress.sin_port = htons(listenPort);
>
> if (bind(listenSocket,
> (struct sockaddr *) &serverAddress,
> sizeof(serverAddress)) < 0) {
> cerr << "cannot bind socket";
> exit(1);
> }
>
> // Wait for connections from clients.
> listen(listenSocket, 5);
>
> while (1) {
> cout << "Waiting for TCP connection on port " << listenPort << "
> ...\n";
>
> // Accept a connection with a client that is requesting one.
> clientAddressLength = sizeof(clientAddress);
> connectSocket = accept(listenSocket,
> (struct sockaddr *) &clientAddress,
> &clientAddressLength);
> if (connectSocket < 0) {
> cerr << "cannot accept connection ";
> exit(1);
> }
>
> //Read from the socket or whatever
> while (recv(connectSocket, line, MAXMSG, 0) > 0) {
> cout << line << "\n";
> }
>
> A client socket is somewhat different.. but there should be lots of
> examples on the web on this...



Sean 01-16-2007 05:04 AM

Re: HEEELLLPPP socket programing instant messaging
 
Thanks for the rely. I am actually trying to make a program that is
both a client and a server. This means, that if you and I are both
running this code on our machines, I can make a call to you, in which
case, you will be the server and I will be the client and you can make
a call to me. So I am not sure if I am going about this the right way
or not.


bjeremy wrote:
> Sean wrote:
> > Hi Everyone,
> > My apologies for a somewhat dump question but I am really stuck. I have
> > been working on this code for two days straight I am dont know what is
> > wrong with it. when I run the code, All I get is Input: and the program
> > quits. I also tried reading this online but I didn't quite get it.
> >
> > What is the diff between sin_addr and sin_addr.s_addr. My understanding
> > is that the latter is the IP address of my machine where as the former
> > is the destination IP address.
> >
> > Also why doesn't the program stop at
> > cout << "Input: ";
> > cin.get(buf, MAX_LINE, '\n');
> >
> > for the user to enter something.
> >
> > I am trying to write an instant messaging program (peer to peer).
> >
> > Below is my code.
> >
> > Thanks in advance
> >
> >
> > #include <netdb.h>
> > #include <netinet/in.h>
> > #include <unistd.h>
> > #include <iostream>
> > #include <arpa/inet.h>
> >
> > #define MAX_LINE 100
> > #define LINE_ARRAY_SIZE (MAX_LINE+1)
> > #define PORT 15002
> >
> > using namespace std;
> >
> > int main()
> > {
> > int socketDescriptor;
> > struct sockaddr_in serverAddress;
> > char buf[LINE_ARRAY_SIZE], c;
> > struct hostent *hostInfo;
> >
> > cout << "Enter IP address: ";
> > cin.get(buf, MAX_LINE, '\n');
> >
> > socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
> > if (socketDescriptor < 0) {
> > cerr << "cannot create socket\n";
> > exit(1);
> > }
> >
> > hostInfo = gethostbyname(buf);
> > if (hostInfo == NULL) {
> > cout << "problem interpreting host: " << buf << "\n";
> > exit(1);
> > }
> >
> > memset(&serverAddress, 0, sizeof(serverAddress));
> > serverAddress.sin_family = AF_INET;
> > serverAddress.sin_port = htons(PORT);
> > inet_aton(buf, &(serverAddress.sin_addr));
> > serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
> > if( bind(socketDescriptor, (struct sockaddr *) &serverAddress,
> > sizeof(serverAddress)) )
> > cerr << "bind() failed" ;
> >
> > memset(buf, 0x0, LINE_ARRAY_SIZE);
> > cout << "Input: ";
> > cin.get(buf, MAX_LINE, '\n');
> > while (cin.get(c) && c != '\n')
> > ;
> >
> >
> > // Send the line to the server.
> > if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) {
> > cerr << "cannot send data ";
> > close(socketDescriptor);
> > exit(1);
> > }
> >
> > // Zero out the buffer.
> > memset(buf, 0x0, LINE_ARRAY_SIZE);
> >
> > // Read the modified line back from the server.
> > if (recv(socketDescriptor, buf, MAX_LINE, 0) < 0) {
> > cerr << "didn't get response from server?";
> > close(socketDescriptor);
> > exit(1);
> > }
> >
> > close(socketDescriptor);
> > return 0;
> > }

>
> For your other question as to why your program doesn't stop at Input:.
> The answer is that you previously issued a :
>
> > cout << "Enter IP address: ";
> > cin.get(buf, MAX_LINE, '\n');
> >

> but never cleared the "buf"... so there is still a line in your buffer
> and it is exiting out... However, after you fix this (a few ways of
> doing it, I'll leave it up to you to pick one), you will still have
> some problems... so for you next question the difference between
> sin_addr and s_addr can be confusing... but sin_addr is a member of the
> struct sockaddr_in (internet socket address struct look in
> netinet/in.h)... the member is of type in_addr. Struct in_addr has only
> one member and that is s_addr... s_addr is a 32 bit IPv4 Address
> supposedly in network byte order (big endian). This IP address can be
> any IP Address and is not related to a local host or destination
> address per se.
>
> In your example I really can't tell if you are trying to open a client
> socket or a server socket... Let's say you are trying to set up a
> server socket, you bind to your local default IP Address, but after a
> bind you should issue a listen() and then an accept() to await incoming
> connections (if you use blocking i/o, which it looks like you do this
> call will block).. Once you accept a client connection, then you could
> send/recv data off that connection. But you will use the socket
> descriptor of the new connection, not the descriptor you receved by
> establishing your server socket
>
> // Create socket for listening for client connection requests.
> listenSocket = socket(AF_INET, SOCK_STREAM, 0);
> if (listenSocket < 0) {
> cerr << "cannot create listen socket";
> exit(1);
> }
>
> // Bind listen socket to listen port. First set various fields in
> // the serverAddress structure, then call bind().
> serverAddress.sin_family = AF_INET;
> serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
> serverAddress.sin_port = htons(listenPort);
>
> if (bind(listenSocket,
> (struct sockaddr *) &serverAddress,
> sizeof(serverAddress)) < 0) {
> cerr << "cannot bind socket";
> exit(1);
> }
>
> // Wait for connections from clients.
> listen(listenSocket, 5);
>
> while (1) {
> cout << "Waiting for TCP connection on port " << listenPort << "
> ...\n";
>
> // Accept a connection with a client that is requesting one.
> clientAddressLength = sizeof(clientAddress);
> connectSocket = accept(listenSocket,
> (struct sockaddr *) &clientAddress,
> &clientAddressLength);
> if (connectSocket < 0) {
> cerr << "cannot accept connection ";
> exit(1);
> }
>
> //Read from the socket or whatever
> while (recv(connectSocket, line, MAXMSG, 0) > 0) {
> cout << line << "\n";
> }
>
> A client socket is somewhat different.. but there should be lots of
> examples on the web on this...



Default User 01-16-2007 06:34 PM

Re: HEEELLLPPP socket programing instant messaging - TPA
 
Sean wrote:

> Thanks for the rely.



Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or the group FAQ list:
<http://www.parashift.com/c++-faq-lite/how-to-post.html>

bjeremy 01-16-2007 07:28 PM

Re: HEEELLLPPP socket programing instant messaging
 

Sean wrote:
> Thanks for the rely. I am actually trying to make a program that is
> both a client and a server. This means, that if you and I are both
> running this code on our machines, I can make a call to you, in which
> case, you will be the server and I will be the client and you can make
> a call to me. So I am not sure if I am going about this the right way
> or not.
>


Well if you want to do that you would need to use non-blocking i/o. The
first part of your program would set up a server socket that
listen()-ed to a defined port. The non-blocking i/o would be needed in
order to not wait on the accept(). While you are listening for incoming
connections, you can do other stuff... like open up a client connection
of your own. This is straight forward, but if you are new to socket
programming I suggest you read about non-blocking i/o and
select()/poll().



All times are GMT. The time now is 09:50 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.