|
Thank you for the replies.
When my listening socket binds to IN_ADDRANY, and I pass port 0 to the bind call, doesn't that mean that I can rcv messages from any port number? This should be true, since this is the part that has been working for quite a while.
I realize that when I send a message, that the O/S will pick a source port, but when I do a rcvfrom, won't I be able to catch messages from any UDP port?
Sorry for the stupid questions, I can't seem to find any documentation on this type of a bind call.
Thanks again.
|
|
|
|
|
think a socket is just a wire from one port of client to one port of server.
client can use port 0 (it may be 1350 actually) but client must know port used by server (server is listening on the port).
server is pastive and client is positive for first connection.
includeh10
|
|
|
|
|
Thanks again.
The software is not really a client/server application, although I guess you could think of it that way. The PC communicates with remote units by sending messages, and waiting for replies, but the PC also looks for any unsolicited messsages, and deals with them as well. So, in this regard the PC must act as the server, and client. This is why the listening socket needs to be able to read messages from unkown sources (and this has been working).
Anyway, I think I'll leave it as it is, and find another way to send and recv the new message (without breaking what has been working).
Thanks again for your replies.
|
|
|
|
|
Dave_ wrote:
When my listening socket binds to IN_ADDRANY, and I pass port 0 to the bind call, doesn't that mean that I can rcv messages from any port number? This should be true, since this is the part that has been working for quite a while.
No, that's not correct. When you recieve a message you must use, aka bind to, a port number known to both computers ahead of time. The reason is the client (or sending machine) must know which port to send its message to. The server can only listen on one port at a time. Like someone else pointed out, pick some high random number (below 65535 though) so you don't interfere with ports that have official uses ( those < 1024).
It's like a telephone number. When someone calls you they must know your phone number. You don't care what number they're calling from (that's where IN_ADDRANY comes from), but you'll always be to receive calls at your number.
Don't feel estranged.... socket programming is pretty goofy when you first start doing it.
|
|
|
|
|
Thanks for taking the time to look at this for me.
The application is not actually a server. There are two threads, one for sending, and one for receiving. When the PC sends a message, it will send using a constant source port number of 1594. The hardware responds to that port number, but the PC also needs to listen for unsolicited messages from other port numbersd. This part of the software has been working for years without problems.
I don't understand how I could possibly be recieving messages if when I pass in IN_ADDRANY, and 0 for the port number, and that results in a port number 1679 (for example) after the bind, since most messages (if not all) are coming in on port 1594?
Thanks again, sorry for the lack of knowledge.
|
|
|
|
|
Dave_ wrote:
The application is not actually a server. There are two threads, one for sending, and one for receiving.
This is fine and makes sense.
Dave_ wrote:
When the PC sends a message, it will send using a constant source port number of 1594.
This does not. The source port number applies when you are *sending* a message and should be determined by the operating system when you create the socket. This should not be a constant. The reason is you have no way of knowing (realistically) what ports are being used, so the OS takes care of it for you.
To help clarify:
1. Computer A wants to send a message to computer B
2. Computer B binds to a port (say 2000)
3. Computer A opens a socket connection to B and the OS assigns it a port of 47826 (essentially random from A's point of view) to use
4. Computer A sends a message to port 2000 on B
Now, from A's point of view, 2000 is the *destination* port, and 47826 is the *source* port.
Dave_ wrote:
I don't understand how I could possibly be recieving messages if when I pass in IN_ADDRANY, and 0 for the port number, and that results in a port number 1679 (for example) after the bind, since most messages (if not all) are coming in on port 1594?
See, if your messages are coming in on port 1594 then your server must be listening on the same port to receive them. That's why, for the receiving computer, it doesn't make sense to dynamically let the OS determine the port to bind to. You'll want to explicitly bind to port 1594, not 0.
Forgive me if I'm missing something, but I hope that clears up what I'm trying to say.
|
|
|
|
|
We (here at my company) have talked about the reasons why the original programmer bound the sending port to 1594. I realize this is not the normal thing to do, but given that it is currently done this way, does the rest of it make sense?
We have officially "reserved" UDP 1594 for our systems, so that's why we are not randomly picking one. So when we send, we know that the units are going to reply to port 1594, since we know that we sent on 1594.
The only thing left to sort out is how the listening socket works. If it is bound with IN_ADDRANY, and port 0, there is next to no chance that it is picking 1594 (at least not every single time). So, given that it does actually get messages from 1594, I'm assuming that doing a rcvfrom on this type of bind will let me recv. from unkown port numbers, and not just 1594, since I never used the number "1594" anyhwere near the listeners source code.
This is where I am confused. Most people use sockets the way you described, where the client sends to a known server port, and things interact from there, but this is done differently. In this case, the PC sends most of the initial messages, and waits for replies, but it also collects messages from other ports, such as 502 (Modbus protocol).
I hope I am not sounding like I know more than you do, because I'm sure this is not true, but when it comes to the operation of the existing code, I do know that it works as I described. There are probably better ways to do it, however.
When I wanted to add a third socket to send a broadcast message, things didn't work, so I started to look further into it. The broadcast would go out each NIC, but the source IP was always the primary NIC's IP. So the new socket was created and bound to each NIC's IP, and port 0. The broadcasts were sent properly, but the replies were never seen by the listener. That's how I got to this point.
Sorry for the novel. I'll understand if you want to ignore me now.
Thanks again,
David.
|
|
|
|
|
Heh, I fear this is a case where you have too many "unique" details for me to be much help. It seems like you get the drift of what I was saying, but it doesn't directly apply to you.
|
|
|
|
|
Bubba2146 wrote:
Heh, I fear this is a case where you have too many "unique" details for me to be much help. It seems like you get the drift of what I was saying, but it doesn't directly apply to you.
Thanks for your time.
|
|
|
|
|
I have some code which sets the item data on a list box depending on some data attributes. I have multiple list boxes in my application and always want to set the item data the same way. To do this I need to pass as a parameter the control id of the list box in question. That way I can do a listbox.SetItemData (fieldNum, 1); How do I specify the type of listbox in my code? Here is the prototype and code.
void DataImportDlg2::SetMapType(CListBox list,
LPCTSTR fieldName,
int fieldNum)
{
DbHelper::InputType inputType;
DbHelper dbHelper;
// Set the additional data flag which indicates whether
// the item is a value mapping type or not. 1 indicates it is,
// a 0 means no.
inputType = dbHelper.GetItemsInputType (fieldName);
if (inputType == DbHelper::A)
list.SetItemData (fieldNum, 1);
else
list.SetItemData (fieldNum, 0);
}
I make the call like this:
SetMapType (m_availFieldList, *iter, index);
which gives me a compile error 'cannot convert parameter 1 from 'class CListBox' to 'class CListBox'
Any ideas on what type to make the list parameter?
Thanks in advance,
Bob
|
|
|
|
|
Pass a reference to the list to be updated:
void DataImportDlg2::SetMapType(CListBox<font color="#ff0000">&</font> list,
LPCTSTR fieldName,
int fieldNum)
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
That works, except I have to change my argument name from list, since it thinks I'm referencing the STL list.
Thanks,
Bob
|
|
|
|
|
i very enjoy a database lib:
header file : dbdao.h
lib file : ddao35.lib
dll file : ddao35.dll
in VC5.0 professional version, all of them are there.
but in Visual Studio 6.0 enterprice company version, i can't find last one ddao35.dll, only first two are there.
so every time if i use database, i have to copy ddao35.dll from VC5.0.
i don't know if it is problem of our Visual studio 6.0 or something else.
and, even enjoyable, the lib can't be used by release version, so i often send debug version to customer.
i think i lost something, do u have suggestions?
thx
includeh10
|
|
|
|
|
According to MSDN the file should be included with VC6 in the DAO SDK. Have you tried installing the latest MDAC or getting the latest Platform SDK?
Knowledge base article Q192777 refers to a bug in the files. I don't think that is your problem though.
Michael
Look, try and use your intelligence, man, even if you are a politician. - The Doctor
|
|
|
|
|
i do install everything in Visual studio 6.0.
after installation, i use 'find' to search ddao35.dll in my computer and source CD, no the file.
but ddao35.dll is simply in VC5.0 CD
thx
includeh10
|
|
|
|
|
If I realloc a block of memory and the address has changed to another location I want to free the previous address but it dosent work. way??
has anyone can suggest me another idea.
---Code Example---
double *ptr, *ptr_1;
long N, M;
...
ptr= new double [N];
...
ptr_1=ptr;
if((ptr=(double*)realloc(ptr, M*sizeof(double)))==NULL)
{
printf("Error\n");
exit(1);
}
if(ptr_1!=ptr)
free(ptr_1); ????? -> ERROR Why this is Error?????
|
|
|
|
|
realloc takes care of freeing the old block.
By the way, you shouldn't be mixing new and delete with malloc , realloc and free . Though it may seem to work for your current compiler, this is not guaranteed to be so for other compilers/releases.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
if u call realloc, system will do something for previous allocaled memory (delete or else), so u can't do it again.
but, i think first call should be alloc instead of new.
new and alloc assigns different page, sometimes it will cause trouble.
includeh10
|
|
|
|
|
System does not delete or free old memory block, becuse if I work in a cycle('For') I get System Memory Leak.
|
|
|
|
|
System does not delete or free old memory block...
Yes it does. Probably you're experiencing problems due to your mixing of new and realloc . Try using malloc instead of new .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I do not mix between New & Delete and malloc realloc & free
and still I got System Memory Leak.
I have tried diffrent of variations.
|
|
|
|
|
I strongly doubt you've discovered in realloc . Try to downsize your program to a postable sample and, if the error persists, publish the sample here.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I am allocating a vector of double's, and inside a loop this vector is growing each cycle. So I need to realloc for the new size, but after a few cycles the memory is full.
The sample i post the fisrt time is the sample you need. Just put it in a 'FOR' loop, and increase the a amount of memory allocation. Let me know if you got a memory leak.
|
|
|
|
|
do a simple test u will know trouble.
call malloc, and new then check the addresses assigned by the two calls.
u will find the number from new is much larger.
new is realy on global.
malloc, even GlobalAllocPtr is not.
includeh10
|
|
|
|
|
OK, I think I know ehere your problem lies. When realloc fails, then it is your responsibility to free the old block. I guess this is the memory leask you're having. This sample reallocates till memory exhaustion taking care of the freeing when the exhaustion occurs:
double *ptr, *ptr_1;
long N=100;
ptr=(double *)malloc(N*sizeof(double));
for(;;){
N*=2;
ptr_1=ptr;
if((ptr=(double*)realloc(ptr, N*sizeof(double)))==NULL){
free(ptr_1);
break;
}
}
Please let me know if this solves your problem.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|