Client not able to connect to Server using WinSock in C++ - c++

I am making a simple client server application where the client sends an image file(.jpg) to the server. But, the client is not able to connect to the server. Please tell me where I am going wrong. This is what I have done.
Client:
WSADATA wsaData;
SOCKET m_socket;
SOCKET m_backup;
sockaddr_in con;
SOCKET AcceptSocket;
WComm::WComm()
{
// Initialize Winsock.
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
printf("Error at WSAStartup()\n");
// Create a socket.
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return;
}
m_backup = m_socket;
}
void WComm::connectServer(char *ip, int port)
{
// Connect to a server.
con.sin_family = AF_INET;
con.sin_addr.s_addr = inet_addr(ip);
con.sin_port = htons(port);
if (connect(m_socket, (SOCKADDR*)&con, sizeof(con)) == SOCKET_ERROR) {
printf("Failed to connect.\n");
WSACleanup();
return;
}
}
int WComm::sendData(char *sendbuf)
{
return send(m_socket, sendbuf, strlen(sendbuf), 0);
}
int WComm::recvData(char *recvbuf, int size)
{
int sz = recv(m_socket, recvbuf, size, 0);
recvbuf[sz] = '\0';
return sz;
}
void WComm::closeConnection()
{
closesocket(m_socket);
m_socket = m_backup;
}
void WComm::fileSend(char *fpath)
{
// Extract only filename from given path.
char filename[50];
int i = strlen(fpath);
for (; i>0; i--)if (fpath[i - 1] == '\\')break;
for (int j = 0; i <= (int)strlen(fpath); i++)filename[j++] = fpath[i];
////////////////////////////////////////
ifstream myFile(fpath, ios::in | ios::binary | ios::ate);
int size = (int)myFile.tellg();
myFile.close();
char filesize[10]; itoa(size, filesize, 10);
send(m_socket, filename, strlen(filename), 0);
char rec[32] = ""; recv(m_socket, rec, 32, 0);
send(m_socket, filesize, strlen(filesize), 0);
recv(m_socket, rec, 32, 0);
FILE *fr = fopen("C:\\Images\\abc.jpg", "rb");
while (size > 0)
{
char buffer[1030];
if (size >= 1024)
{
fread(buffer, 1024, 1, fr);
send(m_socket, buffer, 1024, 0);
recv(m_socket, rec, 32, 0);
}
else
{
fread(buffer, size, 1, fr);
buffer[size] = '\0';
send(m_socket, buffer, size, 0);
recv(m_socket, rec, 32, 0);
}
size -= 1024;
}
fclose(fr);
}
WComm w;
void main(int argc, char *argv[])
{
runclient(argv[1], argv[2]);
}
void runclient(char *ip, char *fpath)
{
char rec[32] = "";
// Connect To Server
w.connectServer(ip, 27015);
printf("Connected to server...\n");
// Sending File
w.sendData("FileSend");
w.recvData(rec, 32);
w.fileSend(fpath);
printf("File Sent.............\n");
// Send Close Connection Signal
w.sendData("EndConnection"); w.recvData(rec, 32);
printf("Connection ended......\n");
}
Server:
#include "wcomm.h"
WSADATA wsaData;
SOCKET m_socket;
SOCKET m_backup;
sockaddr_in con;
SOCKET AcceptSocket;
WComm::WComm()
{
// Initialize Winsock.
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
printf("Error at WSAStartup()\n");
// Create a socket.
m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( m_socket == INVALID_SOCKET ) {
printf( "Error at socket(): %ld\n", WSAGetLastError() );
WSACleanup();
return;
}
m_backup = m_socket;
}
void WComm::startServer(int port)
{
// Connect to a server.
con.sin_family = AF_INET;
con.sin_addr.s_addr = inet_addr( "0.0.0.0" );
con.sin_port = htons( port );
if ( bind( m_socket, (SOCKADDR*) &con, sizeof(con) ) == SOCKET_ERROR) {
printf( "Failed to connect.\n" );
WSACleanup();
return;
}
// Listen on the socket.
if ( listen( m_socket, 1 ) == SOCKET_ERROR )
printf( "Error listening on socket.\n");
}
void WComm::waitForClient()
{
AcceptSocket = SOCKET_ERROR;
while ( AcceptSocket == SOCKET_ERROR ) {
AcceptSocket = accept( m_backup, NULL, NULL );
}
m_socket = AcceptSocket;
}
int WComm::sendData(char *sendbuf)
{
return send( m_socket, sendbuf, strlen(sendbuf), 0 );
}
int WComm::recvData(char *recvbuf,int size)
{
int sz = recv( m_socket, recvbuf, size, 0 );
recvbuf[sz] = '\0';
return sz;
}
void WComm::closeConnection()
{
closesocket(m_socket);
m_socket = m_backup;
}
void WComm::fileReceive(char *filename)
{
char rec[50] = "";
recv( m_socket, filename, 32, 0 );
send( m_socket, "OK", strlen("OK"), 0 );
FILE *fw = fopen(filename, "wb");
int recs = recv( m_socket, rec, 32, 0 );
send( m_socket, "OK", strlen("OK"), 0 );
rec[recs]='\0';
int size = atoi(rec);
while(size > 0)
{
char buffer[1030];
if(size>=1024)
{
recv( m_socket, buffer, 1024, 0 );
send( m_socket, "OK", strlen("OK"), 0 );
fwrite(buffer, 1024, 1, fw);
}
else
{
recv( m_socket, buffer, size, 0 );
send( m_socket, "OK", strlen("OK"), 0 );
buffer[size]='\0';
fwrite(buffer, size, 1, fw);
}
size -= 1024;
}
fclose(fw);
}
WComm w;
void main(int argc, char *argv[])
{
runserver();
}
void runserver()
{
// Start Server Daemon
w.startServer(27015);
printf("Server Started........\n");
while (TRUE) {
// Wait until a client connects
w.waitForClient();
printf("Client Connected......\n");
// Work with client
while (TRUE)
{
char rec[50] = "";
w.recvData(rec, 32);
w.sendData("OK");
if (strcmp(rec, "FileSend") == 0)
{
char fname[32] = "";
w.fileReceive(fname);
printf("File Received.........\n");
}
if (strcmp(rec, "EndConnection") == 0)break;
printf("Connection Ended......\n");
}
// Disconnect client
w.closeConnection();
}
}
Also, if I want to send more than 1 image, then what should I do for that? Would going for Generic List be a good idea to hold all the images which I want to send? How to go for this? Please help

Related

WSAGetLastError 10038 in a C++ client

I create a C++ client that connect to a C++ server.
It connect and send correctly data to a server.
I create a separate thread to receive data from the server , and here is the problem that I can't figure it out.
I get this error:
WSAGetLastError 10038
I find that this error because the descriptor is not a socket.
The server send method work correcty, I test it with a telnet client.
This is my client code:
#include <winsock2.h>
#include <windows.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <conio.h>
#include<iostream>
using namespace std;
int hsock;
void *SocketHandler(void*);
int main(int argv, char** argc){
//The port and address you want to connect to
int host_port= 2000;//1101;
char* host_name="10.188.126.198";
pthread_t recept;
//Initialize socket support WINDOWS ONLY!
unsigned short wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 || ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )) {
fprintf(stderr, "Could not find useable sock dll %d\n",WSAGetLastError());
return 0;
}
//Initialize sockets and set any options
int * p_int ;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if(hsock == -1){
printf("Error initializing socket %d\n",WSAGetLastError());
return 0;
}
p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
(setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
printf("Error setting options %d\n", WSAGetLastError());
free(p_int);
return 0;
}
free(p_int);
//Connect to the server
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = inet_addr(host_name);
int *csock ;
csock = (int*)malloc(sizeof(int));
if( (*csock =connect( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr))) == SOCKET_ERROR ){
fprintf(stderr, "Error connecting socket %d\n", WSAGetLastError());
return 0;
}
cout<<"Client connect to :"<< htons(host_port)<<endl;
//Create thread to receive data from the server
// the problem is here as I think
pthread_create(&recept,NULL,SocketHandler,(void *)csock);
/// Send data to the server
char buffer[1024];
int buffer_len = 1024;
int bytecount;
int c;
while(true){
memset(buffer, '\0', buffer_len);
for(char* p=buffer ; (c=getch())!=13 ; p++){
printf("%c", c);
*p = c;
}
if( (bytecount=send(hsock, buffer, strlen(buffer),0))==SOCKET_ERROR){
fprintf(stderr, "Error sending data %d\n", WSAGetLastError());
return 0;
}
printf("Sent bytes %d\n", bytecount);
}
closesocket(hsock);
return 0;
}
void *SocketHandler(void* lp){
int *csock= (int*)lp;
cout<<"Start Listening Thread"<<endl;
char buffer[1024];
int buffer_len = 1024;
int bytecount;
memset(buffer, 0, buffer_len);
while(1){
memset(buffer, 0, buffer_len);
if((bytecount = recv(*csock, buffer, buffer_len, 0))==SOCKET_ERROR){
fprintf(stderr, "Error receiving data %d\n", WSAGetLastError());
break;
}
printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
}
free(csock);
return 0;
}
Function 'connect' returns result, not socket handle (https://msdn.microsoft.com/en-us/library/windows/desktop/ms737625%28v=vs.85%29.aspx). Change it to:
...
if (connect(hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == SOCKET_ERROR) {
fprintf(stderr, "Error connecting socket %d\n", WSAGetLastError());
return 0;
}
*csock = hsock;
...
The parameter that you send to the thread is the csock...
int *csock ;
csock = (int*)malloc(sizeof(int));
...
pthread_create(&recept,NULL,SocketHandler,(void *)csock);
and then you use the csock as a the socket (in the thread)...
int *csock= (int*)lp;
...
if((bytecount = recv(*csock, buffer, buffer_len, 0))==SOCKET_ERROR) {
I think that you need to use the hsock as your socket and not the *csock...
BTW:
In windows you should call it a SOCKET and not int...
Hope it helps...

C++ - send the file periodically through socket

I'm a new comer in this stackoverflow.
I successfully sent a file.txt and received it . And I want to send the file through a socket periodically and receive it periodically, too. This is a server client program. Client should send the data and server should receive it with an interval time.
Anyone know how to do this? I used this way:
need to call a function at periodic time intervals in c++
Problem is the file is not sent.
Here is my client code :
void Inwinsock(){
WSAStartup(MAKEWORD(2,2), &winsock);
if (LOBYTE(winsock.wVersion) != 2 || HIBYTE(winsock.wVersion) != 2 ) {
WSACleanup();
}
}
void ClientSock() {
clientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ZeroMemory(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(6091);
}
int _tmain(int argc, _TCHAR* argv[])
{
Inwinsock();
ClientSock();
start:
if (connect(clientSock, (sockaddr*)&addr, sizeof(addr)) < 0 ) {
Sleep(5000);
goto start;
}
printf("Socket Connected ......... \n");
FILE *File;
char *Buffer;
unsigned long Size;
File = fopen("B:\Filesend.txt","rb");
if(!File){
printf("", WSAGetLastError());
goto END;
}
printf("File open ok ! \n");
fseek(File,0,SEEK_END);
Size = ftell(File);
fseek(File,0,SEEK_SET);
printf("file size succeed...\n");
Buffer = (char*) malloc (Size+1);
fread(Buffer,Size,1,File);
char cisi[10];
sprintf(cisi, "%i", Size);
fclose(File);
printf("sending data....\n");
send(clientSock,cisi,10,0); //file size sent
send(clientSock,Buffer,Size,0); // File Binary sent
free(Buffer);
printf("sending finished....\n");
END:
closesocket(clientSock);
WSACleanup();
getchar();
return 0;
system("PAUSE");
}
and here are my server code :
void iniSocket() {
WSAStartup(MAKEWORD(2,2), &winsock);
if (LOBYTE(winsock.wVersion) != 2 || HIBYTE(winsock.wVersion) != 2) {
WSACleanup();
}
}
void opSock(){
servSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ZeroMemory(&addr , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(6091);
bind(servSocket, (sockaddr*)&addr, sizeof(addr));
}
void sockList(){
if (listen(servSocket, 5) == SOCKET_ERROR ) {
printf("listen error %d\n", WSAGetLastError());
}else
{
printf("listen succeed....\n");
}
}
void receive() {
if(recv(ClientAcc,Filesize,10,0)){
Size = atoi((const char*)Filesize);
printf("File size : %d\n",Size);
}
Buffer = (char*)malloc(Size + 1);
int file_dit, total_file = 0 ;
while(total_file < Size)
{
ZeroMemory(Buffer, Size);
if((file_dit = recv(ClientAcc,Buffer,Size,0)) < 0)
{
goto END;
}
else
{
total_file += file_dit;
File = fopen("fileReceived.txt", "wb");
fwrite((const char*)Buffer,1,file_dit,File);
fclose(File);
Sleep(1000);
}
END:
printf("File received \n");
free(Buffer);
closesocket(ClientAcc);
WSACleanup();
getchar();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
while(1)
{
iniSocket();
opSock();
sockList();
if (ClientAcc = accept(servSocket, (sockaddr*)&incommingAddress, &addresslen))
{
char *ClientIP = inet_ntoa(incommingAddress.sin_addr);
int ClientPort = ntohs (incommingAddress.sin_port);
printf("Client connected ....\n" );
printf("IP : %s:%d\n ", ClientIP, ClientPort);
receive();
}
}
return 0;
system("PAUSE");
}
For the periodic part, you could take everything between the start: and END: labels, and put it in a new function, say, sendMyFile();
Then in the client's _tmain(), between the start: and END: labels,
while (1)
{
sendMyFile();
Sleep( 30000 ); // The interval is 30,000.
}
There are certainly better, more sophisticated ways to do something periodically, but this is a good, simple, educational approach.

recv (winsock) function hangs, though data is available

I am using winsock socket api to send a udp packet with a very high port number, which I expect to be unused at the destination. My intention is to receive back one icmp packet with destination unreachable/port unreachable message. I have created two sockets, one on which I am sending UDP packet and other socket on which I am expecting the icmp packet. The send is successful. The destination returns the ICMP reply as well, this I can verify on wireshark. Now when I do a recv, to receive data, the recv function hangs. My objective is to read the data from recv function, which does not happen.
Any help for understaning/fixing this behavior will be highly appreciated. Thanks in advance.
I am attaching the code snippets here...
void sendPacket(unsigned int socketFd, char *packet, char* remoteIP, char* pingType)
{
int nsent = -1;
int rc = -1;
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(struct addrinfo));
if (strcasecmp(pingType, "UDP")==0)
{
hints.ai_flags = AI_CANONNAME; /* always return canonical name */
hints.ai_family = AF_INET; /* 0, AF_INET, AF_INET6, etc. */
hints.ai_socktype = SOCK_DGRAM; /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */
}
rc = getaddrinfo(remoteIP, NULL, &hints, &res);
if ( rc != 0)
{
printf("... Function: %s\tError setting remote address. Exiting. ... \n", __FUNCTION__);
exit(-1);
}
if (strcasecmp(pingType, "UDP")==0)
{
((struct sockaddr_in *)res->ai_addr)->sin_port = htons(34344);
strcpy(packet, "TIMESTAMP");
}
do
{
if (strcasecmp(pingType, "UDP")==0)
{
nsent=sendto(socketFd, packet, strlen(packet), 0, (struct sockaddr *)res->ai_addr, (socklen_t)res->ai_addrlen);
if (nsent < 0)
{
continue;
}
}
}while(nsent < 0);
return;
}
double receivePacket(int socketFd, struct timeval* tvSend, pingReply** lastReplyNode, char* pingType)
{
ssize_t nRecv = -1;
double rc = -1;
char recvbuf[1024];
do
{
nRecv = recv(socketFd, (char *)recvbuf, 1024, 0);
}
while(nRecv < 0);
if (nRecv < 0)
{
return -1;
}
rc = processPacket(recvbuf, nRecv, tvSend, lastReplyNode, pingType);
if (rc == -1)
{
printf("... Function: %s\tReceiving error in Data/Protocol ...\n", __FUNCTION__);
return -1;
}
return rc;
}
void createSocket(unsigned int *sendSocketFd, unsigned int *receiveSocketFd, char *pingType)
{
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
int err;
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
exit(-1);
}
#endif
#ifdef _WIN32
if (strcasecmp(pingType, "UDP")==0)
{
int rc = -1;
struct sockaddr_in src_address;
unsigned long int length;
int optval = 1;
DWORD Length;
OSVERSIONINFO g_OSVersionInfo;
BOOLEAN g_IsWindowsLonghorn = TRUE;
BOOLEAN g_UseFtosToSetTos = TRUE;
int ret, iVal=0;
unsigned int sz = sizeof(iVal);
g_OSVersionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO);
GetVersionEx( &g_OSVersionInfo );
if( g_OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
if( g_OSVersionInfo.dwMajorVersion >= 6 )
{
g_IsWindowsLonghorn = TRUE;
g_UseFtosToSetTos = TRUE;
}
}
*receiveSocketFd = INVALID_SOCKET;
*receiveSocketFd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (*receiveSocketFd < 0)
{
printf("Function: %s\tReceiving Socket creation error.\tErrNo %d. ...\n", __FUNCTION__, WSAGetLastError());
exit(-1);
}
src_address.sin_family=AF_INET;
src_address.sin_addr.s_addr=inet_addr("x.x.x.x");
src_address.sin_port=htons(0);
rc = bind((SOCKET)*receiveSocketFd,(struct sockaddr *)&src_address,sizeof(src_address));
if (rc < 0)
{
printf("Function: %s\tReceiving Socket bind error.\tErrNo %d. ...\n", __FUNCTION__, WSAGetLastError());
exit(-1);
}
iVal = 30000; // in milliseconds
ret = setsockopt(*receiveSocketFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&iVal, sz);
if (ret == SOCKET_ERROR)
{
printf("%d\n", WSAGetLastError());
return; // Temporary
}
rc = WSAIoctl((SOCKET)*receiveSocketFd, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &length, NULL, NULL);
if (rc == SOCKET_ERROR)
{
printf("Function: %s\tReceiving Socket ioctl error.\tErrNo %d. ...\n", __FUNCTION__, WSAGetLastError());
exit(-1);
}
printf("Function: %s\treceiveSocketFd %d ...\n", __FUNCTION__, *receiveSocketFd);
}
else
{
*receiveSocketFd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (*receiveSocketFd < 0)
{
printf("Function: %s\tReceiving Socket creation error.\tErrNo %d. ...\n", __FUNCTION__, WSAGetLastError());
exit(-1);
}
printf("Function: %s\treceiveSocketFd %d ...\n", __FUNCTION__, *receiveSocketFd);
}
#endif
#ifndef _WIN32
unsigned int size = 1024; /* OK if setsockopt fails */
setsockopt(*receiveSocketFd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
#else
char size[5] = "1024"; /* OK if setsockopt fails */
setsockopt(*receiveSocketFd, SOL_SOCKET, SO_RCVBUF, size, sizeof(size));
#endif
if (strcasecmp(pingType, "UDP")==0)
{
*sendSocketFd = socket(AF_INET, SOCK_DGRAM, 0);
if (*sendSocketFd < 0)
{
printf("Send Socket creation error.");
exit(-1);
}
printf("Function: %s\tsendSocketFd %d ...\n", __FUNCTION__, *sendSocketFd);
}
return;
}
You don't get 'destination unreachable' unless the socket is connected, in the UDP sense, and then you don't get it via recv(), you get it as an errno value from a probably subsequent send().

Error connecting to server by proxy server in c++ socket programming

The code for connection :
cout << "connecting1\n";
WSADATA wsadata;
int iResult = WSAStartup (MAKEWORD(2,2), &wsadata );
if (iResult !=NO_ERROR )
printf("\nmyERROR at WSAStartup()\n");
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("error opening socket"); return -1;
}
struct sockaddr_in sin;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(host.c_str());
sin.sin_family = AF_INET;
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
perror("error connecting to host"); return -1;
}
const int query_len = query.length() + 1; // trailing '\0'
if (send(sock, query.c_str(), query_len, 0) != query_len) {
perror("error sending query"); return -1;
}
const int buf_size = 1024 * 1024;
while (true) {
std::vector<char> buf(buf_size, '\0');
const int recv_len = recv(sock, &buf[0], buf_size - 1, 0);
if (recv_len == -1) {
perror("error receiving response"); return -1;
} else if (recv_len == 0) {
std::cout << std::endl; break;
} else {
std::cout << &buf[0];
fprintf(fp, "%s", &buf[0]);
}
}
In wifi without proxy it works fine, but when we use proxy server, net can be accessed in chrome, but the above code prints
connecting1
error connecting to host
What is the problem ?

TCP Winsock: accept multiple connections/clients

I tried to can multiply clients, and send it to each one.
But it working only for one, after one client connected the server just useless for incoming connections.
while(true)
{
if(Sub = accept(Socket, (sockaddr*)&IncomingAddress, &AddressLen))
{
for(int i = 0; i < MaxUsers; i++)
{
if(!ClientAddress[i].sin_family)
{
ClientAddress[i] = IncomingAddress;
char Version[128], Dir[256], Path[256], URL[128], Message[256];
GetCurrentDirectory(256, Dir);
sprintf(Path, "%s\\Version.ini", Dir);
GetPrivateProfileString("Default", "Version", "1.0.0.0", Version, 128, Path);
GetPrivateProfileString("Default", "URL", "", URL, 128, Path);
GetPrivateProfileString("Default", "Message", "", Message, 256, Path);
send(Sub, Version, 128, 0);
send(Sub, Message, 256, 0);
break;
}
}
continue;
}
}
Of course new clients cannot be accepted because the server handles just accepted client, i.e. the server is busy.
The solution is simple: create a new thread for each accepted client and handle the client session there. Just use _beginthreadex() (#include <process.h>):
unsigned __stdcall ClientSession(void *data)
{
SOCKET client_socket = (SOCKET)data;
// Process the client.
}
int _tmain(int argc, _TCHAR* argv[])
{
...
SOCKET client_socket;
while ((client_socket = accept(server_socket, NULL, NULL))) {
// Create a new thread for the accepted client (also pass the accepted client socket).
unsigned threadID;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ClientSession, (void*)client_socket, 0, &threadID);
}
}
By the way, send()/recv() functions do not guarantee that all the data would be sent/received at one call. Please see the documentation for return value of these functions.
After accepting socket create separate thread for client requests. Then continue wait for new accepting.
For example:
...
while (1)
{
AcceptSocket = SOCKET_ERROR;
while (AcceptSocket == SOCKET_ERROR )
{
AcceptSocket = accept( m_socket, NULL, NULL );
}
printf( "Client Connected.\n");
DWORD dwThreadId;
CreateThread (NULL, 0, ProcessClient, (LPVOID) AcceptSocket, 0, &dwThreadId);
}
...
Where ProcessClient function could be like this:
DWORD WINAPI ProcessClient (LPVOID lpParameter)
{
SOCKET AcceptSocket = (SOCKET) lpParameter;
// Send and receive data.
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[2000]="";
char recvbuf[2000]="";
char timebuf[128];
sprintf(sendbuf, "Hello, it's a test server at %s:%d (commands: 1, 2, exit)\n", ipaddr, port);
bytesSent = send( AcceptSocket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
{
printf( "Error at send hello: %ld\n", WSAGetLastError());
goto fin;
}
while (1)
{
_strtime( timebuf );
ZeroMemory (recvbuf, sizeof(recvbuf));
bytesRecv = recv( AcceptSocket, recvbuf, 32, 0);
printf( "%s Client said: %s\n", timebuf, recvbuf);
if (strcmp(recvbuf, "1") == 0)
{
sprintf(sendbuf, "You typed ONE\n");
//printf("Sent '%s'\n", sendbuf);
bytesSent = send( AcceptSocket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
{
printf( "Error at send: %ld\n", WSAGetLastError());
goto fin;
}
}
else if (strcmp(recvbuf, "2") == 0)
{
sprintf(sendbuf, "You typed TWO\n");
//printf("Sent '%s'\n", sendbuf);
bytesSent = send( AcceptSocket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
{
printf( "Error at send: %ld\n", WSAGetLastError());
goto fin;
}
}
else if (strcmp(recvbuf, "exit") == 0)
{
printf( "Client has logged out\n", WSAGetLastError());
goto fin;
}
else
{
sprintf(sendbuf, "unknown command\n");
//printf("Sent '%s'\n", sendbuf);
bytesSent = send( AcceptSocket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
{
printf( "Error at send: %ld\n", WSAGetLastError());
goto fin;
}
}
}
fin:
printf("Client processed\n");
closesocket(AcceptSocket);
return 0;
}