Hi, I'm relatively new to socket programming in C/C++ but i have read a few tutorials and had a good go at trying to do it. I have got to the point where i have created a kind server that will accept incoming connections and then when the data is recieved, it will display a message box containing the data it recieved as a string.

Server code:

#include <winsock.h>
#include <windows.h>

void LastError(LPTSTR lpszFunction) 
{ 
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;

    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    wsprintf((LPTSTR)lpDisplayBuf, 
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Message Server"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}

HWND hwnd; //this will later be used for the window handle when the interface is implemented
char * ipaddress; //Temp variable, not yet used...

int main ()
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) 
    {
        LastError("WSAStartup()");
        exit(1);
    }

    SOCKET listeningSocket;
    listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (listeningSocket == INVALID_SOCKET)
    {
        LastError("socket()");
        exit(1);
    }

    SOCKADDR_IN serverInfo;
    serverInfo.sin_family = AF_INET;
    serverInfo.sin_addr.s_addr = INADDR_ANY;
    serverInfo.sin_port = htons(1243);

    int ret = bind(listeningSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));
    if (ret == SOCKET_ERROR)
    {
        LastError("bind()");
        exit(1);
    }

    ret = listen(listeningSocket,1);
    if (ret == SOCKET_ERROR)
    {
        LastError("listen()");
        exit(1);
    }

    SOCKET client;
    client = accept(listeningSocket,NULL,NULL);
    if (client == INVALID_SOCKET)
    {
        LastError("accept()");
        send(listeningSocket,"true",4,0);
        exit(1);
    }

    char buffer[256];
    ret = recv(listeningSocket,buffer,256,0);
    if (ret == SOCKET_ERROR)
    {
        LastError("recv()");
    }
    else
    {
        MessageBox(hwnd,buffer,"Message Server",MB_ICONEXCLAMATION);
    }

    closesocket(client);
    closesocket(listeningSocket);
}

Client code:

#include <winsock.h>
#include <windows.h>
#include <stdio.h>

void LastError(LPTSTR lpszFunction) 
{ 
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;

    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    wsprintf((LPTSTR)lpDisplayBuf, 
        TEXT("Function '%s' failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_ICONERROR); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}


HWND hwnd;
char * serverAddress="127.0.0.1";
char buffer[256]="This is the message";
int ret;

int main ()
{
    WSADATA wsaData;
    ret = WSAStartup(MAKEWORD(1, 1), &wsaData);
    if (ret != 0) 
    {
        LastError("WSAStartup()");
        exit(1);
    }

    LPHOSTENT hostEntry;
    in_addr iaHost;
    iaHost.s_addr = inet_addr(serverAddress); 
    hostEntry = gethostbyaddr((const char *)&iaHost, sizeof(struct in_addr), AF_INET);
    
    if (!hostEntry) 
    {
        LastError("gethostbyaddr()");
        exit(1);
    }

    SOCKET sendingSocket;
    sendingSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (sendingSocket == INVALID_SOCKET)
    {
        LastError("socket()");
        exit(1);
    }

    SOCKADDR_IN serverInfo;
    serverInfo.sin_family = AF_INET;
    serverInfo.sin_port = htons(1243);
    serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);

    ret = connect(sendingSocket,(LPSOCKADDR)&serverInfo,sizeof(struct sockaddr));
    if (ret == SOCKET_ERROR)
    {
        LastError("connect()");
	exit(1);
    }

    ret = send(sendingSocket,buffer,256,0);
    if (ret == SOCKET_ERROR)
    {
        LastError("send()");
        exit(1);
    }
    else
    {

        MessageBox(hwnd,"Message has been sent successfully","Client",MB_ICONINFORMATION);

/*      char temp[100];  //not yet finished, ignore this..
        sprintf(temp,"%d BYTES sent",ret);
        MessageBox(0,temp,0,0); */
    }

    closesocket(sendingSocket);

}

For now I am using the loopback IP address to I can connect the server and client on the same computer using a random port number "1243".

Currently the server runs fine and the client does also, but when I run the client, and the message is sent, the server does not seem to recieve the message correctly since a message is displayed saying "recv() failed with error 10057: A request to send or recieve data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied." So Im assuming there is some kind of mistake in the server program or I am doing something wrong when sending the message.

Secondly, I want to be able to run the server remotely and send a message to it using the client. My problem is that I am behind a router and the destination computer is behind a router also, in fact the same one. We share the same IP address. I want to be able to know how to connect to the server when it is running on a computer behind a router. So basically I want to know how to specify which computer will recieve the data when there are a number of different computers behind the same router.

Thanks.

Recommended Answers

All 10 Replies

anyone got any suggestions for either of the problems?

anyone? any suggestions? especially to the IP address problem?

Why no replies?

If you want to connect to your own network by going outside and coming back in you need to know your external IP address, and you need to tell your router to forward your port(1234) to your server computers internal ip address.

Then using your client side code try to connect to your external ip address at port 1234

Sorry about the delay in the replies. I only look at unanswered threads, so when there were about 3 replies, I skipped the thread. If you hadn't bumped the thread, I probably would have taken a look and replied sooner. Anyway the error is in this line of the server code.

ret = recv(listeningSocket,buffer,256,0);

change it to

ret = recv(client,buffer,256,0);

Argh, thanks a lot, I can't believe that the problem was simply writing the name of the wrong socket.

For the IP problem, you know how like any web application that uses sockets, say for MSN Messenger as an example, when you connect to the server and your client application sends requests to the server, and then the server knows exactly where to send the message back to you. I'm assuming they used something along the lines of recvfrom() to do this, but surely if it works without me having to start messin around with the router, then surely I can don't have to do that in order to make mine work.

Okay. As you know, the two protocols are the TCP/IP and UDP protocols. TCP creates a connection that is valid throughout the time the server and client corresponds with each other. Like a telephone conversation. But UDP sends packets to an address, and there is no connection that is valid after the data packet is delivered. This is more like sending a letter through mail. The postman delivers it only if there is something to be delivered.

The difference between recv and recvfrom is that they use 2 different protocols. recv uses TCP/IP and recvfrom uses UDP. You can do what you want to do using both the protocols. At any rate you shold know the server IP address.

From what I gather from your previous posts, you are behind a router, but there are 2 computers that use the router to connect to the internet. So the outside world only knows the router, so they see only one IP address. However, both your computers should have 2 different local IP addresses. You can use them as the server and client IP addresses. Try typing "ipconfig" at the command prompt of the 2 computers. You should get the IP addresses of the server and client. If you substitute 127.0.0.1 with the server local IP address, you should be able to connect to the server using the client code.

Yes thats exactly it. I have tried before entering "ipconfig" at the command line and usually I will see IP assigned to the network, which is something like 192.168.1.65, and i think the loopback IP 127.0.0.1 and I think the address of the router. I am at University at the moment and I will have to re-check this when I get home, but I think that is what shows up, no unique IP address for the local machine. Do you know of any way in which knowing the IP address of the router, and knowing the IP address of my computer on the network 192.168.1.65, that i could use these to connect to it on the port i have chosen in my program, therefore connecting to the router and then in turn connecting to my machine, and to the server running on the port.

I'm glad you understand my query, I find it hard to get across to most people.

Thanks.

If you get 192.168.1.65 as the server local IP address, inputting that instead of 127.0.0.1 in the client code will get you connected to the server address.

e.g in the client code

char * serverAddress="192.168.1.65";

This is my output from the ipconfig command...

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\bOpS^>ipconfig

Windows IP Configuration


Ethernet adapter Wireless Network Connection 2:

        Connection-specific DNS Suffix  . : domain_not_set.invalid
        IP Address. . . . . . . . . . . . : 192.168.1.66
        Subnet Mask . . . . . . . . . . . : 255.255.255.0
        Default Gateway . . . . . . . . . : 192.168.1.1

C:\Documents and Settings\bOpS^>

yes i know how i can do that but actually what i want to be able to do is have the server running on my computer, and then from a computer outside of my network connect to the server, therefore i need the means of connecting to it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.