Jump to content

Client End of Chat Program Freezes

- - - - -

  • Please log in to reply
16 replies to this topic

#1
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
Hello all,

I'm working on a chat program, it works, no errors or warnings.

I've simply copied and pasted the code for the complete Winsock example of MSDN as a base.

When I run the server program, it works, waiting there.

When I run the client program fron the command-line, passing the parameter 'localhost', it stops working and Windows looks for a solution (I doubt it will).

When I debug from Visual C++ 2010 Express Edition, it just opens then closes. I suspect this happens due to the lack of any command-line parameters.

Anyway, I won't to know why the client program freezes, even with the correct parameters.

Here is the link for the execution instructions (with links to the complete code).

Running the Winsock Client and Server Code Sample (Windows)

Thank you,
Jack
Creator, Owner, Webmaster
Brezerd.net

#2
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
Okay, I've fixed the bug; however, there's another problem. I need the user to be able to specify the server address from the program.

So, I write the response to the argv array. However, this causes an invalid null pointer during debug.

Anyone?



#define WIN32_LEAN_AND_MEAN


#include <windows.h>

#include <winsock2.h>

#include <ws2tcpip.h>

#include <stdlib.h>

#include <stdio.h>

#include <iostream>

#include <cstdlib>

using namespace std;



// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib

#pragma comment (lib, "Ws2_32.lib")

#pragma comment (lib, "Mswsock.lib")

#pragma comment (lib, "AdvApi32.lib")



#define DEFAULT_BUFLEN 512

#define DEFAULT_PORT "27015"


int __cdecl main(int argc, char **argv)

{

	WSADATA wsaData;

    SOCKET ConnectSocket = INVALID_SOCKET;

    struct addrinfo *result = NULL,

                    *ptr = NULL,

                    hints;

    char *sendbuf = "Hello World!";

    char recvbuf[DEFAULT_BUFLEN];

    int iResult;

    int recvbuflen = DEFAULT_BUFLEN;

    

    // Validate the parameters

    if (argc != 1) 

	{

        printf("Usage: %s server-name\n", argv[0]);

        return 1;

    }


    // Initialize Winsock

    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);

    if (iResult != 0) 

	{

        printf("Failed to start Winsock. ERROR: %d\n", iResult);

		system("pause");

        return 1;

    }


    ZeroMemory( &hints, sizeof(hints) );

    hints.ai_family = AF_UNSPEC;

    hints.ai_socktype = SOCK_STREAM;

    hints.ai_protocol = IPPROTO_TCP;


    // Resolve the server address and port

    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);

    if ( iResult != 0 ) {

        printf("Address information failed. ERROR: %d\n", iResult);

		system("pause");

        WSACleanup();

        return 1;

    }


    // Attempt to connect to an address until one succeeds

    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {


        // Create a SOCKET for connecting to server

        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 

            ptr->ai_protocol);

        if (ConnectSocket == INVALID_SOCKET) {

            printf("Socket generation failed. ERROR: %ld\n", WSAGetLastError());

            WSACleanup();

			system("pause");

            return 1;

        }


        // Connect to server.

        iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);

        if (iResult == SOCKET_ERROR) 

		{

            closesocket(ConnectSocket);

            ConnectSocket = INVALID_SOCKET;

            continue;

        }


		

		cout<<"Welcome.\n";

		cout<<"Enter server address:";cin>>argv[1];

		cout<<"You:";cin>>sendbuf;

		cout<<"\n";

		system("pause");



        break;

    }


    freeaddrinfo(result);


    if (ConnectSocket == INVALID_SOCKET) {

        printf("Unable to connect to server.\n");

        WSACleanup();

		system("pause");

        return 1;

    }


    // Send an initial buffer

    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );

    if (iResult == SOCKET_ERROR) {

        printf("Sending failed. ERROR: %d\n", WSAGetLastError());

        closesocket(ConnectSocket);

        WSACleanup();

		system("pause");

        return 1;

    }


    printf("Bytes Sent: %ld\n", iResult);


    // shutdown the connection since no more data will be sent

    iResult = shutdown(ConnectSocket, SD_SEND);

    if (iResult == SOCKET_ERROR) {

        printf("Shutdown failed. ERROR: %d\n", WSAGetLastError());

        closesocket(ConnectSocket);

        WSACleanup();

		system("pause");

        return 1;

    }


    // Receive until the peer closes the connection

    do {


        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);

        if ( iResult > 0 )

            printf("Bytes received: %d\n", iResult);

        else if ( iResult == 0 )

            printf("Connection Terminated.\n");

        else

            printf("Failed to Receive data. ERROR: %d\n", WSAGetLastError());

			system("pause");


    } while( iResult > 0 );


    // cleanup

    closesocket(ConnectSocket);

    WSACleanup();

	return 0;

}

Thanks to those who respond,
Jack
Creator, Owner, Webmaster
Brezerd.net

#3
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,719 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
Don't ever write to argv; it's read-only.
sudo rm -rf /

#4
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
LOL, that would probably be a good reason.

Anyway, how would I modify the code to not need command-line arguments?
Jack
Creator, Owner, Webmaster
Brezerd.net

#5
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
What is your intention writing to argv? Can you not store their input in a local variable?
Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#6
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
This code is copied directly from MSDN, with some modifications. I get errors in converting strings to PCSTR.
Jack
Creator, Owner, Webmaster
Brezerd.net

#7
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,719 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
strdup() is your friend.
sudo rm -rf /

#8
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
So it copies and converts a PCSTR to a std::string? The MSDN specification said it takes a PCSTR as a parameter, but I need to convert std::string to a PCSTR.
Jack
Creator, Owner, Webmaster
Brezerd.net

#9
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,719 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
PCSTR is just a typedef of const char *. Just do this:

std::string str = "blah";

PCSTR p = strdup(str.c_str());

.

.

.

free(p);


Depending on what you do with it, you might not even need to copy it.
sudo rm -rf /

#10
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
I want to take in a node name (IPv4, IPv6, DNS, etc.) from the user, and give it to getaddrinfo() using Winsock 2. However, it needs a PCSTR.

Previously (in the example), you had to specify a command-line parameter (into argv).
Jack
Creator, Owner, Webmaster
Brezerd.net

#11
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,719 posts
  • Programming Language:C, Java, C++, PHP, Python, Perl, Assembly, Bash, Others
  • Learning:JavaScript
(PCSTR)argv[1]

Seriously, all PCSTR is is typedef const char *PCSTR.
sudo rm -rf /

#12
hetra

hetra

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 297 posts
  • Location:Australia
  • Programming Language:C, C++, PHP, Python, Delphi/Object Pascal, Assembly
  • Learning:Python, Assembly
std::string node;

	PCSTR PCSTRNode = strdup(node.c_str());


Then I give PCSTRNode to getaddrinfo.

Knowing me and Winsock, this probably isn't correct. Now I "cannot convert from std::string to const char * "(compiler's exact words).

What exactly does getaddrinfo do? MSDN reccommends using GetAddrInfoW, but this is just a Unicode version, with a different data type.

getaddrinfo Function (Windows)

I'm lost...
Jack
Creator, Owner, Webmaster
Brezerd.net




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users