Here is what I have so far
socklen_t cli_size;
struct sockaddr cli;
int in_sock;
/* event from TCP server socket, new connection */
cli_size = sizeof(cli);
try {
if ((in_sock = ::accept(handle,&cli, &cli_size)) < 0) {
throw in_sock;
return NULL;
}
}
catch(int ex) {
cout << "Exception Nr. " << ex << endl;
}
from man page:
On error, -1 is returned, and errno is set appropriately.
Question: I still can't understand where is errno? I need to understand exception
errno is a global integer variable that contains error codes after system calls like accept fails. You might have to include the header file <errno.h> for the variable to be defined.
In your case, you shouldn't throw the value returned by accept but the value of errno:
try
{
if ((in_sock = accept(...)) == -1)
throw errno;
// ...
}
catch (int error)
{
std::cout << "Error code " << error << " (" << std::strerror(error) << ")\n";
}
The function std::strerror is declared in the header file <cstring> and returns a string describing the error.
An important note: The value of errno is only valid if a function returns that it failed. If, in your example, accept succeeds then the value of errno is undefined.
Related
my select function is returning -1 in my server code and on checking error code its returning 10038 which has this description in documentation:-
WSAENOTSOCK
10038
Socket operation on nonsocket.
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.
My code:
nRet = select(nSocket + 1, &fr, &fw, &fe, &tv);
if (nRet > 0)
{
//someone connects or communicates with a message over a dedicated connection
std::cout << "data on port\n";
ProcessRequest();
}
else
{
if (nRet == 0)
{
//No connection or any communication made or you can say that none of the descriptors
//are ready
std::cout << "nothing on port:" << PORT << "\n";
}
else
{
//it failed to connect
std::cout << "it failed" << nRet << "\n";
error = WSAGetLastError();
std::cout << "error: " << error << "\n";
WSACleanup();
exit(EXIT_FAILURE);
}
}
just for clearing socket(),setsockopt(),bind() and listen() calls were successful as they returned 1
Hi I am trying to make a directory in windows with this code
header
#include <direct.h>
script
int main() {
string local = "C:/Program Files (x86)/Mail";
try
{
_mkdir (local.c_str ());
cout << "It is made?";
}
catch(invalid_argument& e)
{
cout << e.what () << " " << (char*) EEXIST;
if (e.what () == (char*) EEXIST) {
cout << e.what () << " " << (char*) EEXIST;
}
return;
}
}
The file is clearly not made, but it is also not making the error it should.
_mkdir won't throw an exception. (This is not python or boost, or any smart middleware)
Read the documentation you were referring to: it returns a value. 0 is OK, -1: error, ask why to errno
Don't ignore the return value. You probably have insufficient rights without UAC elevation to create the directory.
So I finally figured errno out, which for errno you need the <errno.h> header. The complete list of errno codes.
If you want to see what errno code something is throwing lets say
if (
_mkdir(((string)"C:/Program Files (x86)/Mail").c_str()) == 0 ||
errno == 17 /* this is the code for - File exists - */
){
// Do stuff
} else {
int errorCode = errno; // You need to save the code before anything else,
// because something else might change its value
cout << errorCode;
}
I wonder any way to handle inner exceptions of I called exe from c++ code?
My sample code:
char *fProg = "..\\ConsoleApp\\EZF\\EncryptZipFtp.exe";
char *fPath = "C:\\Users\\min\\Desktop\\Foto";
char *fPass = "wxRfsdMKH1994wxRMK";
char command[500];
sprintf (command, "%s %s %s", fProg, fPath, fPass);
try
{
system(command);
}
catch(exception &err)
{
}
You need to check the return value from system() (as you need to check the return value from all C functions). Like this:
int status = system(command);
if (status == -1)
std::cerr << "oops, could not launch " << command << std::endl;
int rc = WEXITSTATUS(status);
if (rc != 0)
std::cerr << "error from " << command << ": " << rc << std::endl;
If the child program is at all well-behaved, it will return nonzero to indicate failure when an unhandled exception occurs.
I begin to develop my tool, which works with net at the TCP level, and have got the following problem:
Creating thread for accept() function of Winsock
I have googled and looked for the references and evereywhere there is info about creating new thread:
It must have DWORD WINAPI (unsigned long __stdcall) in prefix
It must accept LPVOID argument
And such function will be used as the 3rd argument in CreateThread() function as LPTHREAD_START_ROUTINE structure.
But I have got the next error after compiling:
(131) : error C2664: 'CreateThread' : cannot convert parameter 3 from 'DWORD (__stdcall Net::* )(LPVOID)' to 'LPTHREAD_START_ROUTINE'
Here is my code:
#include <iostream>
#include <Windows.h>
#pragma comment(lib, "Ws2_32.lib")
typedef struct Header
{
friend struct Net;
private:
WORD wsa_version;
WSAData wsa_data;
SOCKET sock;
SOCKADDR_IN service;
char *ip;
unsigned short port;
public:
Header(void)
{
wsa_version = 0x202;
ip = "0x7f.0.0.1";
port = 0x51;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
}
} Header;
typedef struct Net
{
private:
int result;
void WSAInit(WSAData *data, WORD *wsa_version)
{
result = WSAStartup(*wsa_version, &(*data));
if(result != NO_ERROR)
{
std::cout << "WSAStartup() failed with the error: " << result << std::endl;
}
else
{
std::cout << (*data).szDescription << " " << (*data).szSystemStatus << std::endl;
}
}
void SocketInit(SOCKET *my_socket)
{
(*my_socket) = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if((*my_socket) == INVALID_SOCKET)
{
std::cout << "Socket initialization failed with the error: " << WSAGetLastError() << std::endl;
WSACleanup();
}
else
{
std::cout << "Socket initialization successful!" << std::endl;
}
}
void SocketBind(SOCKET *my_socket, SOCKADDR_IN *service)
{
result = bind((*my_socket), (SOCKADDR*)&(*service), sizeof(*service));
if(result == SOCKET_ERROR)
{
std::cout << "Socket binding failed with the error: " << WSAGetLastError() << std::endl;
closesocket((*my_socket));
WSACleanup();
}
else
{
std::cout << "Socket binding successful!" << std::endl;
}
result = listen(*my_socket, SOMAXCONN);
if(result == SOCKET_ERROR)
{
std::cout << "Socket listening failed with the error: " << WSAGetLastError() << std::endl;
}
else
{
std::cout << "Listening to the socket..." << std::endl;
}
}
void SocketAccept(SOCKET *my_socket)
{
SOCKET sock_accept = accept((*my_socket), 0, 0);
if(sock_accept == INVALID_SOCKET)
{
std::cout << "Accept failed with the error: " << WSAGetLastError() << std::endl;
closesocket(*my_socket);
WSACleanup();
}
else
{
std::cout << "Client socket connected!" << std::endl;
}
char data[0x400];
result = recv(sock_accept, data, sizeof(data), 0);
}
DWORD WINAPI Threading(LPVOID lpParam)
{
SOCKET *my_socket = (SOCKET*)lpParam;
SocketAccept(my_socket);
}
public:
Net(void)
{
Header *obj_h = new Header();
WSAInit(&obj_h->wsa_data, &obj_h->wsa_version);
SocketInit(&obj_h->sock);
SocketBind(&obj_h->sock, &obj_h->service);
HANDLE thrd = CreateThread(NULL, 0, &Net::Threading, &obj_h->sock, 0, NULL);
delete &obj_h;
}
} Net;
int main(void)
{
Net *obj_net = new Net();
delete &obj_net;
return 0;
}
You cant use C++ non-static member function.
Use a static one
Nestal's answer is correct - CreateThread expects a function, not a method. That said there are so many other things wrong with this sample I don't know if just leaving it there is the responsible thing to do.
First off, the coding style is just bizarre: The sample is nominally written in C++, but actually looks like a C program. If you are going to bother switching from C to C++, then be aware that using "friend" like that, is a strong hint that you are 'doing it wrong'.
The strange style of directly passing references to attributes of friend classes around serves to hide actual code issues: Even once its building its going to fail a lot as there are numerous race conditions: The socket, passed to the thread as a reference: &obj_h->sock will be deleted while Threading is still running. Even if it wasn't deleted, it (and any variable that is referenced from multiple threads) should be qualified as volatile to ensure the compiler doesn't optimize out actually persisting the variable into memory.
Even once you have made the thread proc 'static', passed the parameters safely, sorted out the race conditions, and correctly volatile qualified any shared variables, you will need to add thread synchronization to guard access to shared variables. Again - the code style presented, of directly passing references to values, makes it difficult to know when variables might be read and written from different threads - making a synchronization strategy difficult to implement consistently.
Good luck.
im just starting to learn about sockets and i have been given this code, and i have to make the port lookup logic work. But the problem is i keep getting this run time error and I dont know why?
// portlookup.cpp
// Given a service name, this program displays the corresponding port number.
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
using namespace std;
int main (int argc, char **argv)
{
char service[80]; // This string contains name of desired service
struct servent *pse; // pointer to service information entry
short port; // Port # (in Network Byte Order) of desired service
if (argc < 2)
{
cout << "Please specify a service." << endl;
}
strcpy_s(service, sizeof(service), argv[1]);
WORD wVersion = 0x0202;
WSADATA wsaData;
int iResult = WSAStartup(wVersion, &wsaData); // Returns zero if successful
if (iResult != 0) {
cout << "Insufficient resources to startup WINSOCK." << endl;
return 0;
}
port = htons( (u_short) atoi(service)); // 1st try to convert string to integer
if (port == 0) { // if that doesn't work, call service function
pse = getservbyname(service,NULL);
if (pse) {
port = pse->s_port;
}
else
{
cout << "Invalid service request." << endl;
return INVALID_SOCKET;
}
}
cout << "Service: " << service << endl;
cout << "Port: " << htons(port) << endl;
}
Your problem appears to be that you aren't passing a command line, you check argc < 2, but when it is < 2 you execute the strcpy_s anyway.
In Visual Studio, Got to the Project Properties dialog, from there go to the Debugging page
and add the service name to Command Arguments
And fix your argument checking code
if (argc < 2)
{
//cout << "Please specify a service." << endl;
cerr << "error: no service specified." << endl;
return EXIT_FAILURE; // return some non-zero value to indicate failure.
}
You need to start your program with an argument. The line strcpy_s(service, sizeof(service),argv[1]); assumes you've given the program 1 argument, which will be stored in argv[1].
If you don't run it with any arguments, argv[1] will be NULL and your program will crash.
Make sure to exit if no parameter is specified.
if (argc < 2)
{
cout << "Please specify a service." << endl;
return 0; // exit!
}
also,
port = htons( (u_short) atoi(service));
...
cout << htons(port);