?
Solved

Can it handle multi winsock client connection

Posted on 2005-04-26
12
Medium Priority
?
442 Views
Last Modified: 2012-06-27
Hi Experts,

I am using the code in link to make single server multi clients.

But I am not sure whether it can handle multi winsock client connection. That is multi clients conect at the same time.

May you give any suggestion?

Thanks and Regards,

Turbot

http://msdn.microsoft.com/library/en-us/winsock/winsock/complete_server_code.asp

http://msdn.microsoft.com/library/en-us/winsock/winsock/complete_client_code.asp

 
0
Comment
Question by:turbot_yu
12 Comments
 
LVL 86

Assisted Solution

by:jkr
jkr earned 200 total points
ID: 13872451
No, the server can't do that - you'd have to launch a thread per connection to be able to handle multiple requests at the same time.
0
 

Author Comment

by:turbot_yu
ID: 13872692
What I need is just to collect all the information from different client.
May I not use multi theread, just use a loop or while (true)
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 800 total points
ID: 13875113
>>>> May I not use multi theread, just use a loop or while (true)

Yes, you could do that, but either you have set the sockets to non-blocking by

   unsigned long d = 1;
   ioctrlsocket(socket, FIONBIO, &d);

and ignore SOCKET_ERROR with GetLastError() ==WSAEWOULDBLOCK  after accept or recv:

  bytesRecv = recv(socket, buf, bufSiz, 0);
  if (bytesRecv == SOCKET_ERROR && GetLastError() ==WSAEWOULDBLOCK)  
  {
        Sleep(10);     // sleep a little while 10 msec
        continue;       // continue loop
  }

or you need to call select with timeout *before* calling accept or recv

#define NET_SUCCESS 0
#define NET_TIMEOUT 1
#define NET_ERROR    -1

unsigned long selectRead(SOCKET sockHost, int msecWait)
{
    int     result = 0;

    /* fd_set manages an array of sockets */
    fd_set          readSockets;
    struct timeval  tval;

    /* set host sockat as first and only element */
    FD_ZERO(&readSockets);
    FD_SET(sockHost, &readSockets);

    return NET_SUCCESS;
    /* init timeout */
    tval.tv_sec  = msecWait / 1000;
    tval.tv_usec = (msecWait % 1000) * 1000;

    result = select(sockHost + 1, &readSockets, NULL, NULL, &tval);

    if (result == 0)
        return NET_TIMEOUT;
    else if (result == SOCKET_ERROR)
        return NET_ERROR;

    return NET_SUCCESS;
}
   
That can be used like

  while (true)
  {
     if (selectRead(m_socket, 100) == NET_SUCCESS)
     {
           SOCKET acceptSocket = accept(m_socket, NULL, NULL);
           // the accept will succeed cause select was successful
           
           ...
     }
     // do other idle stuff
  }

Regards, Alex
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 4

Assisted Solution

by:smpoojary
smpoojary earned 1000 total points
ID: 13875314
1)In that link, the sever is sending and receiving data to and from clients. For this you have to use thread.
2)If your server only receiving data from client and the client only sending data to server. Then no need to use thread.
-Mahesh
0
 
LVL 4

Assisted Solution

by:smpoojary
smpoojary earned 1000 total points
ID: 13875476
I had modified the program in that link. It is like this
server.c
---------
#include <stdio.h>
#include "winsock2.h"

void main() {

    // Initialize Winsock.
    WSADATA wsaData;
    int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
    if ( iResult != NO_ERROR )
        printf("Error at WSAStartup()\n");

    // Create a socket.
    SOCKET m_socket;
    m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if ( m_socket == INVALID_SOCKET ) {
        printf( "Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return;
    }

    // Bind the socket.
    sockaddr_in service;

    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    service.sin_port = htons( 27015 );

    if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
        printf( "bind() failed.\n" );
        closesocket(m_socket);
        return;
    }
   
    // Listen on the socket.
    if ( listen( m_socket, 1 ) == SOCKET_ERROR )
        printf( "Error listening on socket.\n");

    // Accept connections.
    SOCKET AcceptSocket;

    printf( "Waiting for a client to connect...\n" );
    while (1) {
        AcceptSocket = accept( m_socket, NULL, NULL );
        recv(AcceptSocket, recvbuf, 32, 0);
      printf( "Message Recd: %s\n", recvbuf );
      closesocket(AcceptSocket);        
    }
    closesocket(m_socket);
    return;
}

client.c
--------
#include <stdio.h>
#include "winsock2.h"

void main() {

    // Initialize Winsock.
    WSADATA wsaData;
    int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
    if ( iResult != NO_ERROR )
        printf("Error at WSAStartup()\n");

    // Create a socket.
    SOCKET m_socket;
    m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if ( m_socket == INVALID_SOCKET ) {
        printf( "Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return;
    }

    // Connect to a server.
    sockaddr_in clientService;

    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    clientService.sin_port = htons( 27015 );

    if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
        printf( "Failed to connect.\n" );
        WSACleanup();
        return;
    }

    // Send and receive data.
    int bytesSent;
    char sendbuf[32] = "Client: Sending data.";

    bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
    printf( "Bytes Sent: %ld\n", bytesSent );

    closesocket(m_socket);

     return;
}

-Mahesh
0
 
LVL 4

Assisted Solution

by:smpoojary
smpoojary earned 1000 total points
ID: 13875665
some correction you have to put       char recvbuf[32] = "";    in server.c  and
include following header files in server.c as well as client.c
#include <stdio.h>      /* for printf(), fprintf() */
#include <winsock.h>    /* for socket(),... */
#include <stdlib.h>     /* for exit() */

and include lib file in Project Settings (VC++)
wsock32.lib

-Mahesh
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 800 total points
ID: 13876695
>>>> you have to put      char recvbuf[32] = "";

Better:

        char recvbuf[32]  = { '\0' };

The latter will set zeroes to all characters.

>>>> #include <winsock.h>    /* for socket(),... */

you should take

#include <winsock2.h>

on Windows platform.
 

Regards, Alex
0
 
LVL 4

Assisted Solution

by:smpoojary
smpoojary earned 1000 total points
ID: 13882688
hi Alex,

   I had checked this program and also I got correct result what I expected used header file winsock.h instead of winsock2.h in windows. Can you explain more about this why I have to use winsock2.h instead of winsock.h. Any reason? Both are header files in windows for socket.

  -Mahesh
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 800 total points
ID: 13883428
>>>> Can you explain more about this why I have to use winsock2.h instead of winsock.h.

winsock.h corresponds to version 1.1 of Windows Sockets specification while winsock2.h reflects to version 2.2. I am using winsock2.h since 10 years, so you couldn't say winsock2.h is very new. Most probably, only a few or none of the Winsock2 enhancements will bother you - the only one I needed was improvement of FD_READ macro, but I think you should rely on the newer standard.

Note, other platforms do not change to winsock2.h but made the update to the newer specification in winsock.h.

Regards, Alex
0
 
LVL 4

Assisted Solution

by:smpoojary
smpoojary earned 1000 total points
ID: 13883481
Thanks Alex. I am newer to this socket programming in windows. But I know well in UNIX. Thanks once again.
-Mahesh
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 800 total points
ID: 13883960
You could learn more following that link:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcewinsk/html/ceconbackwardcompatibilityforwindowssockets11applications.asp

BTW, the appropriate library to link against is ws2_32.lib (import lib to ws2_32.dll).

Regards
0
 
LVL 4

Assisted Solution

by:smpoojary
smpoojary earned 1000 total points
ID: 13884239
thanks
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question