Thread: Extra Characters

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    17

    Extra Characters

    I'm using the code below to send messages between the through the two programs.
    It works, but I'm getting a lot of excess characters and I have no idea where they came from...
    http://i56.tinypic.com/5by613.png

    Server:
    Code:
    #pragma comment(lib, "ws2_32")
    
    #include <winsock2.h>	
    #include <iostream>
    
    using namespace std;
    
    int StartServerListening(unsigned short port);
    
    void EndServer(int socket);
    
    HANDLE Hthread; // Used to handle our threads
    HANDLE Hmutex; // A mutex is bascially a memory spot we can lock so nothing writes to it as we read form it.. That could cause issues
    
    FD_SET masterSet; // This basically is our list of sockets that we will lock and unlock with out mutexHandle
    
    // A FD_SET has a few data members:
    // - fd_count - the number of file descriptors in the set
    // - fd_array - the array of file descriptors
    
    // We can use these little macros to help edit the FD_SET
    // - FD_SET(a socket, FD_SET to manipulate) - add a scoket to the set
    // - FD_ZERO(FD_SET to manipulate) - zero a set
    // - FD_CLR(a socket, FD_SET to manipulate) - remove a socket from the set
    // - FD_ISSET(a socket, FD_SET to manipulate) - checks if the socket is already in the set
    
    
    bool gQuitFlag = false;// A flag ill use to terminate the program if it goes terribly wrong
    
    // AcceptThread() - a This function will accept ALL incomming connections Then add to the FD_SET list
    void AcceptThread(int* serverSocket)
    {
    	SetConsoleTitle(L"Server");
        int mySocket = *serverSocket;    // Copy my socket over to a local variable
    
        
        for (;;)
        {
        
            unsigned int clientSocket = accept(mySocket, 0, 0);    // Do a normal accept
    
            if (clientSocket == SOCKET_ERROR)
            {
                gQuitFlag = true; // Quit this thread
                return;
            }
            else
            {
                WaitForSingleObject(Hmutex, INFINITE);// Lock the mutex and wait for it
                FD_SET(clientSocket, &masterSet);// Add this socket to the master set using FD_SET()
                ReleaseMutex(Hmutex);// Unlock the mutex
    
                
                cout << "client on " << clientSocket <<" connected.\n" << endl;// Let everyone know someone just joined
            }
        }
    }
    
    int main()
    {
        int serverSocket;
        serverSocket = StartServerListening(7700);
    
        if (serverSocket == -1)
        {
            return 1;
        }
    
        
        Hmutex = CreateMutex(NULL, false, NULL);// Create the mutex
    
        if (Hmutex == NULL)
        {
            EndServer(serverSocket);
            return 1;
        }
    
        
        int thread;// Create the thread
        Hthread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AcceptThread, &serverSocket, 0, (LPDWORD)&thread);
        
        if (Hthread == NULL)
        {
            EndServer(serverSocket);
            return 1;
        }
        Sleep(100);// Let the AcceptThread start up, cheap method, but oh well -.-;
    
        FD_ZERO(&masterSet); // Always zero your sets before you use them, you know.. just incase...
    
        for (;;)
        {
            if (gQuitFlag)
            {
                break;
            }
    
    
            WaitForSingleObject(Hmutex, INFINITE);        // Lock the mutex
    
            FD_SET TempSet = masterSet; // Make a temp location so we can unlock our mutex and let our accept thread run ASAP
            ReleaseMutex(Hmutex);        // Unlock the mutex
    
            if (TempSet.fd_count == 0) // If a set is empty and we call form it, it returns a error, thats too much coding for me
            {                              // So we will simply check if there is anything in it, if so we will do something, else screw it -.-;
                continue;
            }
    
            // select() has 5 member datas of use to us they are
            // - the number of file descriptors
            // - a FD_SET  checks readability
            // - a FD_SET  checks for writeability
            // - a FD_SET  checks for errors
            // - a wait time
            timeval waitTime; // Set up our interval
            waitTime.tv_sec = 0; // Set it to 0
            waitTime.tv_usec = 0; // Set it to 0
    
            int result = select(TempSet.fd_count, &TempSet, NULL, NULL, &waitTime); // Select a socket in out TempSet
    
    
            if (result == 0) // Check for 0's agian
            {
                continue; // = Empty
            }
    
            if (result == SOCKET_ERROR)
            {
                continue;
            }
    
            for (unsigned int i = 0; i < TempSet.fd_count; i++)
            {
                unsigned int clientSocket = TempSet.fd_array[i];
    
                int nBytes;
                #define MAX_MESSAGE_SIZE 4096
                char buffer[MAX_MESSAGE_SIZE];
    
                unsigned long messageSize;
                nBytes = recv(clientSocket, (char*)&messageSize, sizeof(messageSize), 0);
    
                if (nBytes == SOCKET_ERROR)
                {
                    int error = WSAGetLastError();// Main error you will get here is if the other client suddenly disconnects or loses power or something similar
                    if (error == WSAECONNRESET)
                    {
                        WaitForSingleObject(Hmutex, INFINITE);    // Lock our mutex
                        FD_CLR(clientSocket, &masterSet);            // Remove the socket from our master set
                        ReleaseMutex(Hmutex);                    // Unlock our mutex
                        closesocket(clientSocket);                    // Close the socket on our side so our computer cleans up properly
                        cout << "Server: Client on "<< clientSocket << " has Disconnected." << endl; // Tell everyone the person left
                        continue;
                    }
                    else
                    {
                        gQuitFlag = true;
                        break;
                    }
                }
                if (nBytes == 0) // Called if the user exits and calls closesocket() on THEIR side. They stops ending data, thus 0 bytes, ets jsut remove them from the set
                {
                    WaitForSingleObject(Hmutex, INFINITE);    // Lock our mutex
                    FD_CLR(clientSocket, &masterSet);        // Remove the socket from our master set
                    ReleaseMutex(Hmutex);                // Unlock our mutex
                    closesocket(clientSocket);                // Close the socket on our side, so our computer cleans up properly
                    cout << "Server: Client on " << clientSocket << " has disconnected" << "\n";// Quick Message to the rest in the room
                    continue;// On to the next one!
                }
                messageSize = ntohl(messageSize);
                nBytes = recv(clientSocket, buffer, messageSize, 0);
                if (nBytes == SOCKET_ERROR)
                {
                    cout << "Server: I failed the message sir!\n";
                    gQuitFlag = true;
                    break;
                }
                buffer[messageSize] = ' ';
                cout << "Server: Client [" <<  clientSocket << "]: " << buffer << "\n";
            }
        }
    
        EndServer(serverSocket);
        cout << "Server: Press any key to shut me down....\n";
        cin.get();
        return 0;
    }
    
    
    int StartServerListening(unsigned short port)
    {
        int error;
        WSAData wsaData;
        if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
        {
            cout << "Server: Winsock is being a .......... Sir!\n";
            return -1;
        }
        int mySocket = socket(AF_INET, SOCK_STREAM, 0);
        if (mySocket == SOCKET_ERROR)
        {
            cout << "Server: ****ing Socket is stuck closed!\n";
            return -1;
        }
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = htons(port);
        server.sin_addr.s_addr = INADDR_ANY;
        if (bind(mySocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
        {
            cout << "Server: Sorry Sir! My Bind Failed!\n";
            closesocket(mySocket);
            return -1;
        }
        if (listen(mySocket, 5) == SOCKET_ERROR)
        {
            cout << "Server: I failed to listen -.-;\n";
            closesocket(mySocket);
            return -1;
        }
        cout << "Server: Starting Up.. READY!\n";
        return mySocket;
    }
    void EndServer(int socket)
    {
        WaitForSingleObject(Hthread, INFINITE);// Kill thread and handle
        CloseHandle(Hthread);
        CloseHandle(Hmutex);
        closesocket(socket);
        WSACleanup();
        cout << "Server: Shuting down master.\n";
    }


    Client:
    Code:
    #pragma comment(lib, "ws2_32")
    
    int StartClient(unsigned short port, const char* serverName);
    void EndClient(int clientSocket);
    
    #include <winsock2.h>
    #include <iostream>
    using namespace std;
    	
    int main()
    {
    	SetConsoleTitle(L"Client");
        int mySocket;
        mySocket = StartClient(7700, "localhost");
    	
        if (mySocket == -1)
        {
            EndClient(mySocket);
            return 1;
        }
        int nBytes;
        #define MAX_MESSAGE_SIZE 4096
        char buffer[MAX_MESSAGE_SIZE];
        cout << "Message to send (exit to exit) > ";
        for (;;)
        {
            gets(buffer);
            if (strcmp(buffer, "exit") == 0)
            {
                break;
            }
            unsigned long messageSize = strlen(buffer);
            messageSize = htonl(messageSize);
            if ((nBytes = send(mySocket, (char*)&messageSize, sizeof(messageSize), 0)) == SOCKET_ERROR)
            {
                cout << "Client: Error Sending.\n";
            }
            messageSize = ntohl(messageSize);
            if ((nBytes = send(mySocket, buffer, messageSize, 0)) == SOCKET_ERROR)
            {
                cout << "Client: Error Sending.\n";
            }
            cout << "\n>";
        }
        EndClient(mySocket);
        return 0;
    }
    
    int StartClient(unsigned short port, const char* serverName)
    {
        int error;
        WSAData wsaData;
        if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
        {
            cout << "Client: Error Connecting.\n";
            return -1;
        }
        int mySocket = socket(AF_INET, SOCK_STREAM, 0);
        if (mySocket == SOCKET_ERROR)
        {
            cout << "Client: Error Connecting.\n";
            return -1;
        }
        struct hostent *host_entry;
        if ((host_entry = gethostbyname(serverName)) == NULL)
        {
            cout << "Client: Eror Resolving Host.\n";
        }
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = htons(port);
        server.sin_addr.s_addr = *(unsigned long*) host_entry->h_addr;
        if (connect(mySocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
        {
            cout << "Client: Error Connecting.\n";
        }
        cout << "Client: Connection Successful.\n";
    
        return mySocket;
    }
    
    
    void EndClient(int clientSocket)
    {
        closesocket(clientSocket);
        WSACleanup();
    }

  2. #2
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    Code:
    char buffer[MAX_MESSAGE_SIZE];
    ...
    
    gets(buffer);
    Code:
    nBytes = recv(clientSocket, buffer, messageSize, 0);
    ...
    
    buffer[messageSize] = ' ';
    cout << "Server: Client [" <<  clientSocket << "]: " << buffer << "\n";
    So the client gets input from the user, puts it into char buffer[], and sends it to the server. So far so good. The server notices that a message is waiting (exciting! perhaps his crush is sending a message!) and gets it from the mysterious socket interface. So far, so good. Then the server, wanting to read the message, appends a ' ' to the message. Wait, what? If ' ' signifies the end of a string, how does one send messages with spaces, like "C uses null-terminated strings"?

    Change that ' ' to a (char) 0 or a '\0' and that should fix it.
    Consider this post signed

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    And please DON'T USE gets!!!

  4. #4
    Registered User
    Join Date
    Sep 2010
    Posts
    17
    Quote Originally Posted by bernt View Post
    Code:
    char buffer[MAX_MESSAGE_SIZE];
    ...
    
    gets(buffer);
    Code:
    nBytes = recv(clientSocket, buffer, messageSize, 0);
    ...
    
    buffer[messageSize] = ' ';
    cout << "Server: Client [" <<  clientSocket << "]: " << buffer << "\n";
    So the client gets input from the user, puts it into char buffer[], and sends it to the server. So far so good. The server notices that a message is waiting (exciting! perhaps his crush is sending a message!) and gets it from the mysterious socket interface. So far, so good. Then the server, wanting to read the message, appends a ' ' to the message. Wait, what? If ' ' signifies the end of a string, how does one send messages with spaces, like "C uses null-terminated strings"?

    Change that ' ' to a (char) 0 or a '\0' and that should fix it.
    oh my.. sorry for this thread, i really should've seen that. thanks for the explanation though.

    Quote Originally Posted by rags_to_riches View Post
    And please DON'T USE gets!!!
    okay.. i used scanf instead. can i ask why not though? and whether scanf is the most appropriate alternative?

  5. #5

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange characters in output to terminal
    By hellogamesmaste in forum C Programming
    Replies: 4
    Last Post: 08-30-2009, 10:25 AM
  2. Extra characters in string
    By Tigers! in forum C Programming
    Replies: 10
    Last Post: 07-28-2009, 11:48 PM
  3. Counting the characters from each word from a text file
    By flipguy_ph in forum C Programming
    Replies: 6
    Last Post: 04-27-2009, 05:56 PM
  4. problem with reading characters
    By csvraju in forum C Programming
    Replies: 4
    Last Post: 03-31-2009, 07:59 AM
  5. printing non-ASCII characters (in unicode)
    By dbaryl in forum C Programming
    Replies: 1
    Last Post: 10-25-2002, 01:00 PM