C Board  

Go Back   C Board > Platform Specific Boards > Windows Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 04-21-2005, 04:04 PM   #1
Yah.
 
Morgul's Avatar
 
Join Date: Feb 2005
Posts: 109
Question Winsock Messaging Program

I have tried several times to get winsock to work and my applications online, but to no avail. Recently, I started making a simple messaging program. For testing purpose, i tried to see if it would connect on my own computer, and it did. However, when I try to have a friend connect to me from over the internet, things get into a loop on my end (which is partially my fault for coding it that way), and quickly returns an error on the client end.

Here is my code:
Code:
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>

#define NETWORK_ERROR     -1
#define NETWORK_OK         0
#define ID_MESSAGELIST     100
#define ID_MESSAGE         101
#define ID_NICK            102
#define ID_CONNECT         103
#define ID_DISCONNECT      104
#define ID_HOST            105
#define ID_SEND            106

void ReportError(int, const char *);

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

char szClassName[ ] = "MessengerTest";
HWND hwnd, messagelist;
WORD sockVersion;
WSADATA wsaData;
int iResult;
SOCKET m_socket;
SOCKET AcceptSocket;
bool ishost;

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    MSG messages;
    WNDCLASSEX wincl;

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof (WNDCLASSEX);

    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    if (!RegisterClassEx (&wincl))
        return 0;

    hwnd = CreateWindowEx (
           0,
           szClassName,
           "Messenger Test",
           WS_OVERLAPPEDWINDOW,
           CW_USEDEFAULT,
           CW_USEDEFAULT,
           544,
           375,
           HWND_DESKTOP,
           NULL,
           hThisInstance,
           NULL
           );

    ShowWindow (hwnd, nFunsterStil);

    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }

    return messages.wParam;
}



LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    LPSTR szMessage = "Messages:";
    LPSTR szMessage2 = "Your Nickname:";
    LPSTR szMessage3 = "Enter a Message Here:";
    LPSTR szMessage4 = "Winsock Test: A Messaging Program";
    switch (message)
    {
        case WM_PAINT:
             hdc = BeginPaint(hwnd, &ps);
             SetBkColor(hdc, 0x007500);
             TextOut(hdc, 16, 256, szMessage, strlen(szMessage));
             TextOut(hdc, 16, 150, szMessage2, strlen(szMessage2));
             TextOut(hdc, 16, 200, szMessage3, strlen(szMessage3));
             TextOut(hdc, 16, 16, szMessage4, strlen(szMessage4));
             EndPaint(hwnd, &ps);
             break;
        case WM_CREATE:
            CreateWindow("Button", "Host", WS_BORDER | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 248, 48, 100, 30, hwnd, (HMENU) ID_HOST, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
            CreateWindow("Button", "Send", WS_BORDER | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 160, 151, 100, 30, hwnd, (HMENU) ID_SEND, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
            CreateWindow("Button", "Connect", WS_BORDER | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 16, 48, 100, 30, hwnd, (HMENU) ID_CONNECT, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
            CreateWindow("Button", "Disconnect", WS_BORDER | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 132, 48, 100, 30, hwnd, (HMENU) ID_DISCONNECT, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
            CreateWindow("Edit", "", WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 16, 166, 80, 16, hwnd, (HMENU) ID_NICK, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
            CreateWindow("Edit", "", WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 16, 216, 506, 16, hwnd, (HMENU) ID_MESSAGE, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
            messagelist = CreateWindow("Listbox", "", WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_BORDER | LBS_HASSTRINGS, 16, 272, 506, 60, hwnd, (HMENU) ID_MESSAGELIST, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
            SendMessage(messagelist, LB_ADDSTRING, 0, (LPARAM) "Program Started...");
            break;
        case WM_COMMAND:
             switch(LOWORD(wParam)) {
                 case ID_SEND:
                      break;
                 case ID_HOST:
                      iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
                      if ( iResult != NO_ERROR ) {
                          MessageBox(hwnd, "Error initializing Winsock!", "Error!", MB_ICONSTOP | MB_OK);
                          exit(0);
                      }
                      m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
                      if ( m_socket == INVALID_SOCKET ) {
                         MessageBox(hwnd, "Error at socket():", "Error!", MB_ICONSTOP | MB_OK);
                         MessageBox(hwnd, _itoa(WSAGetLastError(), NULL, 10), "Error!", MB_ICONSTOP | MB_OK);
                         WSACleanup();
                         exit(0);
                      }
                      sockaddr_in service;
                      service.sin_family = AF_INET;
                      service.sin_addr.s_addr = INADDR_ANY;
                      service.sin_port = htons( 27015 );
                      if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
                          MessageBox(hwnd, "bind() Failed!", "Error!", MB_ICONSTOP | MB_OK);
                          closesocket(m_socket);
                          exit(0);
                      }
                      SendMessage(messagelist, LB_ADDSTRING, 0, (LPARAM) "Created Host");
                      SendMessage(messagelist, LB_ADDSTRING, 0, (LPARAM) "Waiting for a Connection...");
                      if ( listen( m_socket, 1 ) == SOCKET_ERROR ) {
                          MessageBox(hwnd, "Error listening on socket!", "Error!", MB_ICONSTOP | MB_OK);
                          exit(0);
                      }
                      while (1) {
                            AcceptSocket = SOCKET_ERROR;
                            while (AcceptSocket == SOCKET_ERROR) {
                                  AcceptSocket = accept( m_socket, NULL, NULL );
                            }
                            SendMessage(messagelist, LB_ADDSTRING, 0, (LPARAM) "Client Connected!");
                            m_socket = AcceptSocket; 
                            break;
                      }
                      ishost = true;
                      break;
                 case ID_CONNECT:
                      iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
                      if ( iResult != NO_ERROR ) {
                           MessageBox(hwnd, "Error initializing Winsock!", "Error!", MB_ICONSTOP | MB_OK);
                           exit(0);
                      }
                      m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
                      if ( m_socket == INVALID_SOCKET ) {
                          MessageBox(hwnd, "Error at socket():", "Error!", MB_ICONSTOP | MB_OK);
                          MessageBox(hwnd, _itoa(WSAGetLastError(), NULL, 10), "Error!", MB_ICONSTOP | MB_OK);
                          WSACleanup();
                          exit(0);
                      }
                      sockaddr_in clientService;
                      clientService.sin_family = AF_INET;
                      clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
                      clientService.sin_port = htons( 27015 );
                      SendMessage(messagelist, LB_ADDSTRING, 0, (LPARAM) "Connecting...");
                      if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
                          MessageBox(hwnd, "Failed to connect.", "Error!", MB_ICONSTOP | MB_OK);
                          WSACleanup();
                          exit(0);
                      }
                      SendMessage(messagelist, LB_ADDSTRING, 0, (LPARAM) "Connected to Host!");
                      break;
                 case ID_DISCONNECT:
                      closesocket(m_socket);
	                  closesocket(AcceptSocket);
                      break;
             }
             break;
        case WM_DESTROY:
             closesocket(m_socket);
	         closesocket(AcceptSocket);
             PostQuitMessage (0);
             break;
        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
I know that the send function doesnt work, I havent tried to fix it becuase i cant really test it.

Another thing is that when you click the host button for instance, I tell the messages box to say that you have completed making a host, waiting for client to connect, etc. However, it doesnt disply these messages untill after a connection. is this becuase it has to wait to go through the message loop again to process it?

Could it be my firewall, if the code is alright? I have Mcafee, but it also didnt work on a friend of mine's computer and he has a different firewall.


This is really bugging me. Much of the winsock part of the code came directly or indirectly from online tutorials, wo I do not understand why it is failing me.

All help is very much appreciated. Thanks in advance .

I am using Dev-C++ 4.9.9.2, and like I said I have Mcafee for a firewall.
__________________
Sic vis pacum para bellum. If you want peace, prepare for war.
Morgul is offline   Reply With Quote
Old 04-22-2005, 02:14 AM   #2
Politics&Cpp geek
 
Da-Nuka's Avatar
 
Join Date: Oct 2004
Posts: 104
I had the same problem. (Atleast my code was okay, and it worked in a LAN).
If you have the chance, try your program in a LAN, without firewalls and other protective programs.

Over internett, there are several things which may disturb your program, for example firewalls, hardware-firewalls(on your connection/router/host), and most important: ROUTERS.
If you are not connected directly to the internett, you also have to setup your router to forward the ports you want to use.

On internett, you can allways connect from the innside to outside,
but inncomming connections from the outside are a HUGE problem.

How do messaging services like MSN fix this problem?
I think they simply use a SERVER, which everyone connects to, and then avoid the problem.

So if you want to test your program, i would reccomend to test on a local LAN without firewalls, or ANY other protective program or configurations.
__________________
http://livebad.com/nuka
Da-Nuka
Da-Nuka is offline   Reply With Quote
Old 04-22-2005, 04:04 AM   #3
Registered User
 
Join Date: Jan 2005
Posts: 847
Quote:
Another thing is that when you click the host button for instance, I tell the messages box to say that you have completed making a host, waiting for client to connect, etc. However, it doesnt disply these messages untill after a connection. is this becuase it has to wait to go through the message loop again to process it?
yes.
It isn't a good Idea to use functions that take time (like accept called on a blocking socket) in a window procedure, this will make your pgram unresponsive.
You should use at least another thread and have your thread send messages to your main window which can display the status messages to the user.

Last edited by Quantum1024; 04-22-2005 at 04:08 AM.
Quantum1024 is offline   Reply With Quote
Old 04-22-2005, 01:33 PM   #4
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 2,845
Code:
while (1) {
   AcceptSocket = SOCKET_ERROR;
   while (AcceptSocket == SOCKET_ERROR) {
      AcceptSocket = accept( m_socket, NULL, NULL );
   }
   SendMessage(messagelist, LB_ADDSTRING, 0, (LPARAM) "Client Connected!");
   m_socket = AcceptSocket; 
   break;
}
First of all, it is a very bad idea to put an endless loop in the same thread as your UI. This should be done on a different thread, or with asynchronous sockets.

Second, the reason your friend cant connect to you is probably because you are behind a firewall or a router (as others have mentioned). Therefore, you just stay suck in that endless loop, and your program appears frozen. You are binding to port 27015, so you need to forward that port on your router, and open it up in your firewall.
bithub is offline   Reply With Quote
Old 04-22-2005, 09:40 PM   #5
Yah.
 
Morgul's Avatar
 
Join Date: Feb 2005
Posts: 109
I took everything you all said into account. I fixed the program so that it used a thread to accept connections, which I should have done in the first place. The messages are all sent now fine. I opened port 27015 on my computer, and will test tomorrow to see if it now works.

if it doesnt work, i will test on a LAN.

If big games use servers, how do they get around having to send out info? Do thay have client query the server for the info? If so, how would that work?
__________________
Sic vis pacum para bellum. If you want peace, prepare for war.

Last edited by Morgul; 04-22-2005 at 09:43 PM. Reason: Messages
Morgul is offline   Reply With Quote
Old 04-23-2005, 12:48 AM   #6
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 2,845
Quote:
If big games use servers, how do they get around having to send out info? Do thay have client query the server for the info? If so, how would that work?
Once a TCP connection has been established, there is nothing that keeps the server from sending the client arbitrary data at arbitrary times.
bithub is offline   Reply With Quote
Old 04-23-2005, 02:03 PM   #7
Yah.
 
Morgul's Avatar
 
Join Date: Feb 2005
Posts: 109
Oh ok I should have realized that.


One last thing. Say I am writing a server for a game. I know that when one person connects, they get bound to a socket. When I want multiple ppl to connect, they would all get bound to the same socket right? Then, when I send info to a socket, they would all get that info? I wouldn't have to go through a list of connections or something?
__________________
Sic vis pacum para bellum. If you want peace, prepare for war.
Morgul is offline   Reply With Quote
Old 04-23-2005, 03:25 PM   #8
Registered User
 
Join Date: Jan 2005
Posts: 847
Quote:
Originally Posted by Morgul
Oh ok I should have realized that.
One last thing. Say I am writing a server for a game. I know that when one person connects, they get bound to a socket. When I want multiple ppl to connect, they would all get bound to the same socket right?
No, each time you accept a new connection accept returns a new socket and the socket you passed to accept keeps listening. If you wanted all sockets to receive you would have to send that data to each socket.
Quantum1024 is offline   Reply With Quote
Old 04-23-2005, 06:05 PM   #9
Yah.
 
Morgul's Avatar
 
Join Date: Feb 2005
Posts: 109
So I'd want to make an array of sockets. Alright.



Thanks for all your help everyone. I haven't tested it yet but I am pretty sure it will work. I am going to test it now, I'll post if it works or doesn't.
__________________
Sic vis pacum para bellum. If you want peace, prepare for war.
Morgul is offline   Reply With Quote
Old 04-23-2005, 08:00 PM   #10
Registered User
 
Join Date: Jan 2005
Posts: 847
Quote:
Originally Posted by Morgul
So I'd want to make an array of sockets. Alright.
.
That's one appraoch another is to pass the socket handle to a newly created thread. If you're going to have an array of sockets then you will probably want to set them to none-blocking mode otherwise a recv operation could block on a socket and the others will be left waiting.
Quantum1024 is offline   Reply With Quote
Old 04-23-2005, 09:37 PM   #11
Yah.
 
Morgul's Avatar
 
Join Date: Feb 2005
Posts: 109
Yah nonblocking mode is a definite. I didnt test it becuase i was busy hooking up my new lan, but i will tomorrow morning.


You guys have all been a great help. I thank you for everything you have done.
__________________
Sic vis pacum para bellum. If you want peace, prepare for war.
Morgul is offline   Reply With Quote
Old 04-25-2005, 02:42 PM   #12
Yah.
 
Morgul's Avatar
 
Join Date: Feb 2005
Posts: 109
If i am doing this:

Code:
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
wouldn't that connect to myself? Don't I need to change that to whatever the ipaddress is of whoever I am connecting to? That is my problem isn't it?
__________________
Sic vis pacum para bellum. If you want peace, prepare for war.
Morgul is offline   Reply With Quote
Old 04-25-2005, 03:39 PM   #13
Registered User
 
Join Date: Jan 2005
Posts: 847
yes, 127.0.0.1 is your local computer. Set it to the IP you want to connect to or set it from user input giving the user the choice of what to connect to.
Quantum1024 is offline   Reply With Quote
Old 04-25-2005, 04:00 PM   #14
Yah.
 
Morgul's Avatar
 
Join Date: Feb 2005
Posts: 109
That is why it wasn't working. Thanks.
__________________
Sic vis pacum para bellum. If you want peace, prepare for war.
Morgul is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Can someome help me with a program please? WinterInChicago C++ Programming 3 09-21-2006 10:58 PM
Need help with my program... Noah C Programming 2 03-11-2006 07:49 PM
my server program auto shut down hanhao Networking/Device Communication 1 03-13-2004 10:49 PM
Please could someone help me with my 8-function calculator program? Geeth Asokan C Programming 2 05-10-2002 04:16 PM
Possible Networking Program Design :: Winsock kuphryn Windows Programming 3 05-04-2002 06:20 PM


All times are GMT -6. The time now is 09:52 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22