in the last days I try to make a multiprocess program with IPC mechanism, but in the server side part the program return an error in the recv, near the end the last section of the program. It compile on a linux system with gcc, without others flag.
So, I will admire who try help to make work the program totally. Thank you
1. There's no C++ code in there. It's 99% C and the tiny amount of C++ there is, it's just abuse of std::string to make it work basically as C.
2. Your main() is 1700 lines long! Have you ever heard of functions?
3. Magic numbers everywhere. string *agreements[23];
int done[60][22];
Each one of those should have things like const int max_agreements = 23;
Then usage becomes
Code:
while(i2 < max_agreements)
{
s = strdup(territories[labour].t->agreements[i2]->c_str() );
4. Poor variable names, and poor scope.
> struct diplomatic *dipl, *dipl2, *dipl3;
a) these should be local to whatever inner loop is most appropriate for them.
b) whenever you start putting numeric suffixes on variables, you're doing something wrong.
> i, i2, i3, i4, i5,
Even worse!
Your IPC between your two processes is completely broken.
Code:
int shared_var;
int main ( ) {
shared_var = 22;
if ( fork() == 0 ) {
shared_var = 42;
} else {
// you will NEVER see shared_var change to 42 in this process
}
}
> n = recv(fd_arrivals, m, sizeof(char) * 20, MSG_NOSIGNAL );
The valid return values for recv are
-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
-1 is an error
0 is remote closed the connection
anything else is varying levels of success.
You have the same problem on send() as well. You're assuming single calls to send() / recv() always transmit the whole buffer in one go. This is simply not true for a SOCK_STREAM.
Here is now I might wrap send() to ensure a whole buffer is sent.
Code:
ssize_t my_send(int sockfd, const void *buf, size_t len, int flags) {
ssize_t total_sent = 0;
char *bp = buf;
while ( len > 0 ) {
ssize_t sent = send(sockfd, bp, len, flags);
if ( sent > 0 ) {
// some success, advance the buffer and decrease
// the remainder len
bp += sent;
len -= (size_t)sent;
total_sent += sent; // the total
} else if ( sent == 0 ) {
// remote closed the connection
return sent;
} else {
// error
return sent;
}
}
return total_sent;
}
... the program return an error in the recv, near the end the last section of the program. ...
From the docs about recv:
RETURN VALUE
Upon successful completion, recv() shall return the length of the message in bytes. If no messages are available to be received and the peer has performed an orderly shutdown, recv() shall return 0. Otherwise, -1 shall be returned and errno set to indicate the error.
ERRORS
The recv() function shall fail if:
[EAGAIN] or [EWOULDBLOCK]
The socket's file descriptor is marked O_NONBLOCK and no data is waiting to be received; or MSG_OOB is set and no out-of-band data is available and either the socket's file descriptor is marked O_NONBLOCK or the socket does not support blocking to await out-of-band data.
[EBADF]
The socket argument is not a valid file descriptor.
[ECONNRESET]
A connection was forcibly closed by a peer.
[EINTR]
The recv() function was interrupted by a signal that was caught, before any data was available.
[EINVAL]
The MSG_OOB flag is set and no out-of-band data is available.
[ENOTCONN]
A receive is attempted on a connection-mode socket that is not connected.
[ENOTSOCK]
The socket argument does not refer to a socket.
[EOPNOTSUPP]
The specified flags are not supported for this socket type or protocol.
[ETIMEDOUT]
The connection timed out during connection establishment, or due to a transmission timeout on active connection.
The recv() function may fail if:
[EIO]
An I/O error occurred while reading from or writing to the file system.
[ENOBUFS]
Insufficient resources were available in the system to perform the operation.
[ENOMEM]
Insufficient memory was available to fulfill the request.
1. There's no C++ code in there. It's 99% C and the tiny amount of C++ there is, it's just abuse of std::string to make it work basically as C.
2. Your main() is 1700 lines long! Have you ever heard of functions?
3. Magic numbers everywhere. string *agreements[23];
int done[60][22];
Each one of those should have things like const int max_agreements = 23;
Then usage becomes
Code:
while(i2 < max_agreements)
{
s = strdup(territories[labour].t->agreements[i2]->c_str() );
4. Poor variable names, and poor scope.
> struct diplomatic *dipl, *dipl2, *dipl3;
a) these should be local to whatever inner loop is most appropriate for them.
b) whenever you start putting numeric suffixes on variables, you're doing something wrong.
> i, i2, i3, i4, i5,
Even worse!
Your IPC between your two processes is completely broken.
Code:
int shared_var;
int main ( ) {
shared_var = 22;
if ( fork() == 0 ) {
shared_var = 42;
} else {
// you will NEVER see shared_var change to 42 in this process
}
}
> n = recv(fd_arrivals, m, sizeof(char) * 20, MSG_NOSIGNAL );
The valid return values for recv are
-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
-1 is an error
0 is remote closed the connection
anything else is varying levels of success.
You have the same problem on send() as well. You're assuming single calls to send() / recv() always transmit the whole buffer in one go. This is simply not true for a SOCK_STREAM.
Here is now I might wrap send() to ensure a whole buffer is sent.
Code:
ssize_t my_send(int sockfd, const void *buf, size_t len, int flags) {
ssize_t total_sent = 0;
char *bp = buf;
while ( len > 0 ) {
ssize_t sent = send(sockfd, bp, len, flags);
if ( sent > 0 ) {
// some success, advance the buffer and decrease
// the remainder len
bp += sent;
len -= (size_t)sent;
total_sent += sent; // the total
} else if ( sent == 0 ) {
// remote closed the connection
return sent;
} else {
// error
return sent;
}
}
return total_sent;
}
I prefer write about operation of my program, why the style it is not my trouble, why I program during my spare time.
My problem is about the recv in the server side part, after the client reply with 2kB of data for every called process and the recv return me error ( -1 ) with errno value of 9 (EBADF), but I cannot find where I broken the accepted socket and how.
> I prefer write about operation of my program, why the style it is not my trouble,
...
> but I cannot find where I broken the accepted socket and how.
Until you realise these are not independent problems, you're gonna keep failing.
Put it this way,
- if you were my student, you'd get an instant F, even if it did work.
- if you were on my team at work, you'd probably get fired.
I'm not going to waste any more time digging through your mess.
There is a bug that is escaped by my debugging and now the problem it is the same ... obviously
I added somethings near the start of the main function, for avoid other problems during parallel processing.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.