i use this (http://www.codeproject.com/KB/IP/Socks.aspx) lib in my socket programing in c++
and copy the socks.h in include folder and write this code:
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>
#include "socks.h"
#define PORT 1001 // the port client will be connecting to
#define MAXDATASIZE 100
static void ReadThread(void* lp);
int socketId;
int main(int argc, char* argv[])
{
const char temp[]="GET / HTTP/1.0\r\n\r\n";
CSocks cs;
cs.SetVersion(SOCKS_VER4);
cs.SetSocksPort(1080);
cs.SetDestinationPort(1001);
cs.SetDestinationAddress("192.168.11.97");
cs.SetSocksAddress("192.168.11.97");
//cs.SetVersion(SOCKS_VER5);
//cs.SetSocksAddress("128.0.21.200");
socketId = cs.Connect();
// if failed
if (cs.m_IsError)
{
printf( "\n%s", cs.GetLastErrorMessage());
getch();
return 0;
}
// send packet for requesting to a server
if(socketId > 0)
{
send(socketId, temp, strlen(temp), 0);
HANDLE ReadThreadID; // handle for read thread id
HANDLE handle; // handle for thread handle
handle = CreateThread ((LPSECURITY_ATTRIBUTES)NULL, // No security attributes.
(DWORD)0, // Use same stack size.
(LPTHREAD_START_ROUTINE)ReadThread, // Thread procedure.
(LPVOID)(void*)NULL, // Parameter to pass.
(DWORD)0, // Run immediately.
(LPDWORD)&ReadThreadID);
WaitForSingleObject(handle, INFINITE);
}
else
{
printf("\nSocks Server / Destination Server not started..");
}
closesocket(socketId);
getch();
return 0;
}
// Thread Proc for reading from server socket.
static void ReadThread(void* lp)
{
int numbytes;
char buf[MAXDATASIZE];
while(1)
{
if ((numbytes=recv(socketId, buf, MAXDATASIZE-1, 0)) == -1)
{
printf("\nServer / Socks Server has been closed Receive thread Closed\0");
break;
}
if (numbytes == 0) break;
buf[numbytes] = '\0';
printf("Received: %s\r\n",buf);
send(socketId,buf,strlen(buf),0);
}
}
but when compile this i get an error .
pls help me
thanks
To use sockets you need to link your executable with Ws2_32.lib. It will fix the link error that you have mentioned in comments.
According to the MSDN documentation for closesocket, you need to link to Ws2_32.lib.
Related
I'm new to networking and I want to write a simple, Client-side TCP/IP script; however, I encounter an issue when using select() to receive the server's answer.
I want to use select because I need the timeout functionality. I am using select() in a custom function with a non-zero timeout value, generating a DLL out of it, then calling the function in a client main().
Everything works as intended, except the timeout. Either I receive the message instantly (which is good), or the select() function times out instantly (which is not). It seems to me like the timeout value is not taken into account at all.
Here is the code I am using. I included the function in which select() is placed, as well as the client-side implementation.
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <time.h>
#pragma comment(lib, "Ws2_32.lib")
int ReceiveClientMessage()
{
int iResult = -1;
FD_SET ReadSet;
int Socket_notifs = 0;
struct timeval timeout;
timeout.tv_sec = 20000000;
timeout.tv_usec = 0;
FD_ZERO(&ReadSet);
FD_SET(socket_Client, &ReadSet);
Socket_notifs = select(0, &ReadSet, NULL, NULL, &timeout);
if (Socket_notifs == SOCKET_ERROR)
{
printf("Select returned with error %d\n", WSAGetLastError());
return 1;
}
printf("Select successful\n");
if (Socket_notifs > 0)
{
int receiving_buffer_length = DEFAULT_BUFLEN;
char receiving_buffer[DEFAULT_BUFLEN] = "";
// Start receiving
iResult = recv(socket_Client, receiving_buffer, receiving_buffer_length, 0);
if (iResult > 0)
// Message received, display save yada yada
else
// Error receiving
}
else if (Socket_notifs == 0)
{
// Timeout
printf("Select timed out\n\n");
return 2;
}
else
{
// Other issue with select
printf("Unknown error with Select\n\n");
return 3;
}
return 0;
}
//----------------------------------------------------------------
// Client main()
string message, response;
while (true)
{
/* Part where we send a message, irrelevant here */
// Receive a message on client side
iResult = -1;
iResult = ReceiveClientMessage();
cout << iResult << endl;
if (iResult != 0)
// Error, clean up and break
else
// Display message
}
I tried to remove most irrelevant parts of my code, and only left the parts relevant to the select, timeout and receive implementation.
I have already tried setting various values for timeout.tv_sec and timeout.tv_usec (from 20 to 20000000), in case it wasn't a value in seconds or something, without results. Sometimes I send a message, and instantly see the "Select timed out" prompt (which, from my understanding, should not happen). Any idea on how to solve this (either by finding out why the timeout values are not taken into account, or by using another method that has a timeout functionality)?
I'm trying to handle signals while listen socket in syscall select.
Problem: I have the working loop with select call. select waits for socket descriptor is ready.
There is need to break loop by SIGINT or SIGQUIT and correct close resources and exit the programm.
Below code is
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <error.h>
#include <errno.h>
#include <signal.h>
#include <syslog.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
bool bBreakJob = false;
void sig_handler(int sig)
{
switch(sig)
{
case SIGHUP:
//rneed to reload config
break;
case SIGINT:
printf("SIGINT \n");
bBreakJob = true;
openlog("mydaemon", LOG_PID | LOG_CONS, LOG_DAEMON);
syslog(LOG_INFO, "Catched SIGINT");
closelog();
break;
case SIGQUIT:
printf("SIGQUIT \n");
openlog("mydaemon", LOG_PID | LOG_CONS, LOG_DAEMON);
syslog(LOG_INFO, "Catched SIGQUIT");
bBreakJob = true;
break;
case SIGPIPE:
printf("SIGPIPE \n");
break;
}
}
int main(int argc, char** argv)
{
struct sigaction act, oact;
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGHUP);
sigaddset(&set, SIGPIPE);
sigaddset(&set, SIGQUIT);
sigprocmask(SIG_UNBLOCK, &set, NULL);
act.sa_mask = set;
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigaction(SIGINT, &act, NULL);
sigaction(SIGHUP, &act, NULL);
sigaction(SIGPIPE, &act, NULL);
sigaction(SIGQUIT, &act, NULL);
int fds[0], res, fmax;
fd_set wset;
fd_set rset;
//next line code to open socket
int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
int iFlags = fcntl(listen_socket, F_GETFL);
iFlags |= O_NONBLOCK;
fcntl(listen_socket, F_SETFL, iFlags);
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(4000);
bind(listen_socket, (struct sockaddr *)&sin, sizeof(sin));
listen(listen_socket, 20);
fds[0] = listen_socket;
FD_ZERO(&wset);
FD_SET(fds[0], &wset);
fmax = fds[0] + 1;
while (FD_ISSET(fds[0], &wset))
{
rset = wset;
res = select(fmax, &rset, NULL, NULL, NULL);
if (res < 0)
{
if (errno == EINTR)
{ //debug message
printf("Loop broken by select's result EINTR");
break;
} else
{
printf("select(...) fails in listed loop. errno %d (%s)", errno, strerror(errno));
exit(1);
}
}
else if (res == 0)
{
//if timeout is handled
}
else if (res > 0)
{
if (FD_ISSET(fds[0], &rset))
{
//Handle socket input
}
}
if(bBreakJob)
{
printf("Loop broken by signal handler");
break;
}
} //while( 1 );
FD_CLR(fds[0], &wset);
if(bBreakJob)
{ //debug message
printf("signal SIGINT is handled ");
}
}
SIGINT never reaches the sig_handler. In IDE QtCreator I've tried to debug. select just interrupted and then return to listen. The condition "if (errno == EINTR)" is not reached even. Ther is no debug messages either in console either no in syslog. And in the same time SIGQUIT works fine: sig_handler is called and the condition "if (errno == EINTR)" is reached too.
As you can see, I've tried to check SIGINT in to ways: with flag from signal handler, and from result of select
I've tried to found answer in topic Not able to catch SIGINT signal while using select(). But cannot found the solution. This problem I meet in other WEB-resources, but there is no solution too.
SIGINT signal is sened from command line: "kill -s 2 (PID)"
UPD Problem has solved. The issue was in debugger. Under debugger SIGINT does not working properly. Running the programm without debugger working fine as expected.
The interaction of select and signals is tricky, because the signal could always arrive right before you call select. Here are two ways to wake up a select loop from a signal handler:
The "self-pipe trick": Create a pipe and add the read end to your select read set. From your signal handler, write one byte to the write end of this pipe, and it will make the select return immediately (because input is ready).
Rather than pass NULL as the final argument to select, pass a pointer to a timeval that is a global variable. Within your signal handler, make the timeval 0 seconds. Hence, if a signal arrives before you call select, select will ask for a 0 timeout and return immediately.
I have a client/server communicate through eventfd. If either client or server call close(fd) I would like the other end to find out (like file descriptor is closed now). I tried to use select with non-zero timeout, it always return 0 which is timeout. I saw people suggesting use fcntl it doesn't seems to be working either. Any suggestions?
Addtion Details (omitted non important part code, you can see here for how to exchange file descriptor detail code:
It is multi processes application. Server process created eventfd by calling
struct msghdr control_message;
int fd = eventfd(0,0);
*CMSG_DATA(control_message) = fd;
message.msg_control = &control_message;
sendmsg(socket_fd, & message,0); //send this to client
From client side:
recvmsg(socket_fd, & message,0);
//loop using CMSG_NXTHDR(&message, control_message)
int fd = *(int *) CMSG_DATA(contro_message);
Then on server side:
close(fd);
On Client side:
int rc;
rc = dup2(fd,fd);
rc is never invalid.
Checking for a closed file descriptor? How about this?
#include <errno.h>
#include <stdio.h>
#include <string.h>
static void checkit ()
{
int rc;
rc = dup2(2, 2);
if ( rc == -1 )
printf("error %d on dup2(2, 2): %s\n", errno, strerror(errno));
else
printf("dup2 successful\n");
write(2, "still working\n", 14);
}
int main (int argc, char **argv)
{
int rc;
checkit();
close(2);
checkit();
return 0;
}
Running it generates this output:
dup2 successful
still working
error 9 on dup2(2, 2): Bad file descriptor
If this is a multi-threaded application using poll and you want poll to return when the file descriptor is closed by another thread, POLLERR, POLLHUP, or POLLNVAL might help.
Multi-Threaded Version using Poll
And here's a sample that shows how to detect a closed fd with poll (POLLNVAL is the event) in a multi-threaded program:
#include <errno.h>
#include <poll.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static void *run_poll (void *arg)
{
struct pollfd fds[1];
int rc;
fds[0].fd = 2;
fds[0].events = POLLERR | POLLHUP | POLLNVAL;
//
// Poll indefinitely
//
printf("starting poll\n");
fflush(stdout);
rc = poll((struct pollfd *) &fds, 1, -1);
if ( rc == -1 )
{
printf("POLL returned error %d: %s\n", errno, strerror(errno));
}
else
{
printf("POLL returned %d (revents = 0x%08x): %s %s %s\n",
rc,
fds[0].revents,
( ( fds[0].revents & POLLERR ) ? "pollerr" : "noerr" ),
( ( fds[0].revents & POLLHUP ) ? "pollhup" : "nohup" ),
( ( fds[0].revents & POLLNVAL ) ? "pollnval" : "nonval" ));
}
return NULL;
}
int main (int argc, char **argv)
{
pthread_t thread;
int rc;
rc = pthread_create(&thread, NULL, run_poll, NULL);
usleep(100);
printf("closing stderr\n");
close(2);
usleep(100);
return 0;
}
This generates the output
starting poll
closing stderr
POLL returned 1 (revents = 0x00000020): noerr nohup pollnval
I'm writting an server using the multithread technique.
The idea is :
-I will use a socket (m_Server) to accept when the client connect.
-After accept, I'll use another port (t_Socket[i]) to communicate with that client.
It's simple like that. But it's took me about a week to get this far (Because I have a little bit knowledge about socket and I didn't know anything about multithread before).
Here is my code on server :
#include "stdafx.h"
#include "testServer.h"
#include "afxsock.h"
#include "conio.h"
#include "Player.h"
#include <stdio.h>
#include "../functions.h"
#include <iostream>
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define MAX_THREADS 1
CSocket *p_Socket=new CSocket[MAX_THREADS];
CWinApp theApp;
int count=0;
DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
int i=count;
cout<<"Send : ";
m_Send(p_Socket[i]);
return 1;
}
int m_Send(CSocket &m_Socket)
{
char Msg[100];
int MsgSize;
cin.getline(Msg,100);
MsgSize=strlen(Msg);
m_Socket.Send(&MsgSize,sizeof(int));
m_Socket.Send(Msg,MsgSize);
return MsgSize;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
if(AfxSocketInit()==false)
{
cout<<"Initialize Library Failed"<<endl;
return false;
}
int playerIndex=0;
CSocket m_Server;
HANDLE hThreadArray[MAX_THREADS];
DWORD dwThreadIdArray[MAX_THREADS];
if(m_Server.Create(5770)==0)
{
cout<<"Can not create Socket"<<endl;
cout<<m_Server.GetLastError();
}
else
{
cout<<"Successfully initialize server"<<endl;
}
m_Server.Listen(5);
for(int i=0;i<MAX_THREADS;i++)
{
if(m_Server.Accept(p_Socket[i]))
{
cout<<"Player "<<i+1<<" connected!"<<endl;
}
}
for(int i=0;i<MAX_THREADS;i++)
{
hThreadArray[i]=CreateThread(
NULL,
0,
MyThreadFunction,
NULL,
0,
dwThreadIdArray);
//m_Send(p_Socket[i]); (1)
count++;
}
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
for(int i=0;i<MAX_THREADS;i++)
{
p_Socket[i].Close();
}
m_Server.Close();
cout<<"Close all connections"<<endl;
getch();
}
}
else
{
_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
nRetCode = 1;
}
return nRetCode;
}
The problem is :
-After the m_Server accept a connection. The p_Socket in the multithread function doesn't receive the right connection.
-But, look at the line I write a comment with number (1) : //m_Send(p_Socket[i]); (1).
If I run that line instead of the CreateThread line, the program will doing well. But that will make my program become single threaded.
BTW, the MAX_THREADS I set it to 1 because I want to test the code in the simpliest case. I think the problem in my code is the p_Socket[i] can't pass into a multithread function.
I have search for a solution about this for nearly 2 days. So I decided to post a question here hoping for someone will take a look at it.
Thank you for reading my question and sorry about my bad English.
One big problem is that you use a 'count' global to communicate the array index to the handler thread. That is just wrong and will not work.
Instead of passing the 'dwThreadIdArray' as the last parameter in the CreateThread API, pass in the counter 'i'.
Also, the overall structure of your server is atypical. Usually, the Accept() loop runs forever and ceates a client<>server handler thread immediately after Accept() returns, passing a socket handle/pointer as the last void* param. Your code seems to wait, running a for-loop, until MAX_THREADS clients have connected before creating the handler threads in yet another loop. It this your intended behaviour?
I have a quick question. I set this client up as a sort of example, so I do not do a lot of extra work with it; I wanted to get the basic idea working first. I have it working so far, with one exception:
If I start it up, I can see the data being sent across on the other side (I use python+twisted). I can write with no problems, the problem comes when I read. On the server side, I am able to see the text coming in and being sent back out again. But on the client side, things are delayed. I have to send three commands to see something coming out.
for example:
I send hello <newline> cruel <newline> world<newline> and get hello echoed back to me, only after I hit enter on world.
Could someone point out why or give me some hints?
Here is the code.
#include <openssl/ssl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <cstdio>
//used for printing an error and then exiting.
inline void error(const char* message)
{
fprintf(stderr, "%s\n", message);
exit(EXIT_FAILURE);
}
//the buffer size we will be working with:
#define MAX_BUFF 4096
int main()
{
int ret; //used for holding bytes read.
int flag = 1; //our IOCTL flag.
char buff[MAX_BUFF]; //a buffer for holding i/o data.
fd_set rdesc, wdesc, srset, swset; //file descriptor sets.
timeval tv; //used for holding the time select should wait.
SSL_CTX* context = NULL; //ssl context.
SSL* ssl = NULL; //main ssl object.
sockaddr_in addr; //server socket address.
int sock = 0;
//clean out the struct:
bzero(&addr, sizeof(sockaddr_in));
//then fill it in.
addr.sin_family = AF_INET;
addr.sin_port = htons(4000);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
//create the socket
sock=socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
error("Error creating initial socket.");
}
//initialize SSL.
SSL_load_error_strings();
SSL_library_init();
//create the ssl context
context = SSL_CTX_new(TLSv1_client_method());
if (!context)
{
error("Could not create SSL context.");
}
//connect the socket to the server.
if (connect(sock, (sockaddr*)&addr, sizeof(sockaddr_in)) < 0)
{
error("Could not connect to specified socket.");
}
//create the ssl object.
ssl = SSL_new(context);
if (!ssl)
{
error("Could not create ssl object.");
}
//try to set the socket as the fd for the ssl object.
if (!SSL_set_fd(ssl, sock))
{
error("Error, could not bind fd to the ssl object.");
}
//link ssl up with the socket.
if (!SSL_connect(ssl))
{
error("Could not perform ssl handshake.");
}
ioctl(sock, FIONBIO, &flag);
//set our file descriptor sets.
FD_SET(fileno(stdin), &wdesc);
FD_SET(sock, &rdesc);
//wait for data, read, then print.
while (1)
{
//we need to zero out our i/o buffer.
bzero(buff, MAX_BUFF);
//initialize our temp fd sets.
srset = rdesc;
swset = wdesc;
//each time select finishes it changes this to how much time it actually slept, so we need to reset it.
tv.tv_usec = 50*1000; //50 ms
tv.tv_sec = 0;
//perform the actual select operation.
select(sock+1, &srset, &swset, NULL, &tv);
//check to see if data was written on stdin (user input)
if (FD_ISSET(fileno(stdin), &swset))
{
//read inputted data.
ret = read(fileno(stdin), buff, MAX_BUFF);
if (ret)
{
//write it to the socket.
SSL_write(ssl, buff, ret);
}
}
//check to see if we received anything.
if (FD_ISSET(sock, &srset))
{
printf("in if.\n");
//read it
ret = SSL_read(ssl, buff, MAX_BUFF);
printf("%d\n", ret);
if (ret)
{
//write it to screen.
printf("%s\n", buff);
}
}
}
return 0;
}