|
I don't know the structure of dBase, I juste have the copy of a .dbf file (containing the field that interressed me) taken in the middle of dozen others .dbf files.
With ODBC, is it possible to work on a single .dbf file, just to read some infos in it (no update to be done) without the whole dBase context or do I have to read the file in another way, like I would do it for a text file ? But, in this case, how to access the correct column/row, skip the kind of header at the beginning of the file, move from a record to another, etc ...
Regards,
DD
|
|
|
|
|
Qadddd wrote:
I don't know the structure of dBase
That's the beauty of ODBC... you have a common way of accessing all databases. Simply read (or write). You can select which field you want to appear, etc...
|
|
|
|
|
yes, I agree that ODBC is not too bad for this reason and also for code compatibility with other databases.
But, I would like to be sure that it allows me to access a single .dbf file without having the whole dBase context installed on my PC. By context, I mean the right access management, the DB manager itself and all these things that turn around the .dbf files...
So, a .dbf file can really be read out of its dBase context via ODBC.
Is the description of the table (and other needed infos) stored in the famous "header" stored at the beginning of the .dbf file and that's why ODBC can understand the content of the file ? Some other applications (i.e. Microsoft Excel) can also open these .dbf files, do they use the file header, do they use ODBC or an kind of internal interface to do the translation ?
Thanks again for you answers
DD
|
|
|
|
|
Hello,
I use the ODBC driver "dBase Files" installed by microsoft.
hereunder is the code I wrote to access the C:\Documents and Settings\dd\Mes documents\GSTAT.DBF file :
#define DBName "DSN=dBASE Files;UID=;PWD:"
...
CDatabase gDB;
CRecordset rs(&gDB);
CString res;
CString ErrMsg;
CString CASHT;
CString NETROOM;
CString DATUM;
int NbRecord;
CString Path = "C:\\Documents and Settings\\dd\\Mes documents\\" ;
CString File = "GSTAT.DBF" ;
ErrMsg = "";
res = "SELECT DATUM,CASHT,NETROOM from ["+File+"]";
// res = "SELECT DATUM,CASHT,NETROOM from ["+File+"] WHERE (DATUM = 20010208)";
// res = "SELECT DATUM,CASHT,NETROOM from ["+File+"] WHERE (DATUM = '20010208')";
// gDB.OpenEx(DBName,CDatabase::noOdbcDialog);
gDB.OpenEx(DBName,CDatabase::forceOdbcDialog );
TRY
{
rs.Open( CRecordset::forwardOnly, res );
NbRecord = rs.GetRecordCount();
}
CATCH(CDBException, e)
{
ErrMsg ="**ERR: "+e->m_strError.Left(70);
}
END_CATCH
if (ErrMsg == "") {
while(!rs.IsEOF()) {
rs.GetFieldValue( "DATUM", DATUM);
rs.GetFieldValue( "CASHT", CASHT);
rs.GetFieldValue( "NETROOM", NETROOM);
rs.MoveNext();
}
}
rs.Close();
gDB.Close();
Used like this, it works but I have some problems :
1) I am obliged go thru the ODBC display to give the name of the file, I can't set it by program ... why ? How can I do this and use the noOdbcDialog option (When I try to use it, ODBC tells me that it can't find GSTAT.DBF)?
Furthermore, ODBC dialog is based on program directory, not on the path. If I add the Path to the name in File variable, ODBC tells me that it can't find C:\Documents and Settings\dd\Mes documents\GSTAT.DBF ...
2) If I add the clause "WHERE" to my request, no record is returned ... why ? Can't I use it ? Am I obliged to read all records and test the DATUM field by program ?
3) what is the format of the date in the file ? Excel says 08/02/2001, Word says 20010208 and DATUM = 2001-02-06 when debugging my code ... When I use a date in format yyyy-mm-dd or dd/mm/yyyy ODBC tells me that my format is not compatible
Thanks in advance
DD
|
|
|
|
|
I think you are almost there!
1) the database problem
When you create your system DSN, you will give it a name (ex dsnMyDatabase). This name will indicate the DBF file name and the driever you are using.
Then you will redefine
#define DBName "DSN=dsnMyDatabase;UID=WD;"
It should do the trick
2)and 3) The Where should work it is probably a problem due to the way dates are defined
try this WHERE DATNUM = #mm/dd/yyyy#
Good luck
|
|
|
|
|
hello,
sorry to bug you again with this stuff, but I need some extra-infos (in fact, I don't use PC database stuff very much (except MySql on which I crated a little application also using ODBC and I am quite a newbie in VC++ )
1) #define DBName "DSN=dsnMyDatabase;UID=WD;"
Ok I was looking for the pannel where I set the access to the database (path, file) during the ODBC configuration and did not find it ... but looking at it a second time, there is a "Use Current directory" set, and if I deselect it, I can precise the path/file ...
So the way id to Create 1 DSN per file in ODBC and done the "gDB.OpenEx(DBName,CDatabase::noOdbcDialog);" with the correct one.
But, in ODBC, should I just give the path and then precise the file in "OpenValue" in the "rs.Open( CRecordset::forwardOnly, OpenValue );" command, or should I give the path and the file name, in this case should I repeat the file name ine the "OpenValue" or not ?
2) Yes, it should work. ok, I will try the WHERE format you proposed me.
Thanks again
DD
|
|
|
|
|
Salut (did not realise you were French too),
Ok when you create your DSN.
1) You go into System DSN
2) Click Add
3) Select dBase, click Finish
4) Enter the Data Source Name (dsnMyDatabase)
And select your database (after having unclicked use current directory)
Then in ODBC, you do not need to repeat the path of your file, simply the name of the DSN. Do I make sense?
Bonne chance!
|
|
|
|
|
re hello !
BadJerry wrote:
did not realise you were French too
my perfect english probably ... ))
BadJerry wrote:
Then in ODBC, you do not need to repeat the path of your file, simply the name of the DSN?
I aggree !
but I for step 4 :
A) the DSN should be set to the directory containing the file.dbf and the I specify the name of the file.dbf in the rs.Open( CRecordset::forwardOnly, SQLCmd )(what I suppose) or
B) the DSN should be set to the directory+file.dbf and then, I have no clue on what SQLCmd has to be in the rs.Open( CRecordset::forwardOnly, SQLCmd) ?
DD
Et merci pour le Bonne chance, je n'ai pas fini de souffrir avec ce que que je suis en train de faire ...
|
|
|
|
|
What you need to do is find the name of your recordset and the name of your fields as they are defined in your DSN.
The easiest way would be to start MS Access and try to import the data from your DSN (Fichier/Donnees externes in an existing mdb).
This way you will get the name of your table and then you can have something like
"Select * from MyTable"
BTW I suspect the table name is the name of the dbf file...
If this works and its for a one off, leave as it is. If you plan to make this a released application, consider using ADO though... There is a good set of classes on CP for ADO.
Une fois que tu auras fait ca une fois, tu verras, ca n'a rien de sorcier!
A+!
|
|
|
|
|
BadJerry wrote:
"Select * from MyTable"
BTW I suspect the table name is the name of the dbf file...
ok, this pleases me !!!
BadJerry wrote:
consider using ADO though...
I am using these files just to pick some basic informations in, no delete, no update, no complicated SQL stuff. The dBase application producing these files will soon desappear to be replaced by something using Oracle ... So I will keep it like that.
But just for my info : what is the advantage of CDaoDatabase compared to CDatabase class ?
The example I looked before was using CDaoDatabase, I took the code and didn't see a lot of benefits using this class. Further more I need to import a lot of code to make it even compile, the CDaoDatabase isn't known while you just add #include "afxdb.h" for Cdatabase ...
BadJerry wrote:
Une fois que tu auras fait ca une fois, tu verras, ca n'a rien de sorcier!
oui, c'est la premiere fois que ca fait mal ...
A la prochaine
DD
|
|
|
|
|
DAO is really for Access databases really... and it is obsolete. I still use it when I need to play with an Access database because it is blinding fast.
ODBC was the MS first attempt at having a universal way to access databases.
ADO is like ODBC but meant to be much faster (it actually is)
So in your case, do not bother with CDaoDatabase or CDaoRecordset
Qadddd wrote:
oui, c'est la premiere fois que ca fait mal ...
Tiens j'ai deja entendu ca mais c'etait pas sur le meme type de forum
|
|
|
|
|
Hello,
my code seems to work correctly, but I have some problems :
1) SELECT in the files returns me no record but an error message: "Impossible de trouver le fichier memo xBase Demande", in english it can be traduced by "impossible to find the requested xBase memo file" ....
If I open the file with Excel and launch my appli accessing the file, all records are correctly selected and returned ... Strange I know, but true. Simple, to test my appli and until I have a better solution, I just open all accessed files with Excel at the same time ...
Any idea on the cause of this problem and its solution?
2) I thought I had a too old version of my ODBC drivers, so I wanted to upgrade them ...
With microsoft, it is never easy to find anything, so what should I upgrade to upgrade my ODBC drivers ? Seems to be MSJet engine ... So I downloaded the lastest MSJet4.0 sp8, but when I want to install it, it refuses to do it and tells me that I should already have at least the sp3 installed to install this sp8 ... The problem is that, when I verify manually the version of the dll, the version corresponds to a sp5 ... So I don't know what to do to perform my installation ...
3) ODBC and MDAC ... are both linked ? if I upgrade ODBC, should I also upgrade MDAC ? and if yes, which version of MDAC should I install (I have the MDAC 2.5 sp2 installed at the moment)?
4) in one of my dbf table, I have to make a selection on an ID to retrieve a record. This ID seems to be numeric but must not be declared as a standard numeric or even text value (I am thinking to an auto incremented value or style like that) because, in my clause WHERE, when I don't use the quotes, ODBC send me a error message saying that my format is not correct, and when I use the quotes, I don't receive the error, but no record is returned (even if my file is opened with Excel ...) is the any other way to write my request ?
Sorry to bug you again with this but I am a little bit stuck
Regards
DD
|
|
|
|
|
I'm currently in the middle of redesigned a larger application.
Previously the application was divided in [too] large chunks (I will use the term chunk to distinguish it from files/modules). Each chunk had a lot of source (mainly .c) files, but only one header (.h) file that had to be included by the routines of that chunk and by other routines that wanted to use that chunk.
Up to now we used precompiled header files to speed up compilation (all files of a chunk had to include their own header file as first file).
Now I want to divide all these chunks in smaller C++ classes. Each class will have its own header (.h) file and source (.cpp) file. My hope is to end up with less includes, less dependencies and thus a faster compilation.
However, what I notice is just the opposite. We try to make a lot of use of STL and Boost templates, but these seem to slow down compilation seriously. On the other hand, we cannot use precompiled headers anymore because each class has its own header file.
In the fantastic book 'Debugging Applications for .Net and Windows', the author, John Robbins, suggests to use one main header file (e.g. ALL.H) that is included (first) by all of our source files. All includes that aren't changed in the last 3 months should be put in that header file (including STL and Windows includes). In our case we would typically include STL and Boost header files in that ALL.H file, but the template constructions even seem to slow down compilations if precompiled header files are used.
How do you organize your header files? How do you use precompiled headers? And what should be the correct way to use them?
(maybe this could be a question for a poll, but it is probably too C++ oriented for that).
Thanks for your help, fellow CPians.
Enjoy life, this is not a rehearsal !!!
|
|
|
|
|
hi all..
i m new to VC++ and i want to know,where i can get info related to accessing databases using DAO,ODBC in VC++.Any books,preferably.
Thanks in advance
|
|
|
|
|
MSDN Library is your friend. If you don't have it yet, go to it's home page and order a subscription license for yourself. This library contains just about every official thing related to Windows programming world.
MSDN Library is also available via the Net for free reading, and I just happened to have a link to the site handling database and data connectivity issues.
MSDN homepage can be found from here[^].
An introduction to database programming with MFC can be found from here[^].
Happy reading !
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Hi...
I'm trying to create a patch. I read the msdn online help but couldnt quite get the steps to create a small update patch.
Can anybody give me a clue or other sites that i can refer to on how to get this done?
Thank you
|
|
|
|
|
This depends solely on what type of a patch you are planning to create.
Naturally, the most easiest way to patch a program is to replace it's binary executable or library files. This just means that you create an installer which searches or asks for the correct directory, and then dumps it's contents there, overwriting old files as fit.
If you have a gaming application that contains a huge file for resources such as scripts, models, sounds etc then dumping a new file is not really an option (Nobody wants to download a patch of 200 Mb in size). In this case, your best bet is to originally design the resource files to be patchable, that is, you use an encoding or encryption algorithm to which you have the appropriate decoding mechanism. Then you just read the client's file, decode it, make necessary changes, and re-encode the file.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
Thanks for ur reply.
I'm very new at this thing. If you dont mind, can u pls direct me to a site or resource that can help me?
FYI, I just want to make a small upgrade to the previous program where only new functionalities will be introduced.
What do I need and where do I start?
Thank you in advance...
|
|
|
|
|
Hmm..
You could specify a bit more clearly of what you are planning to do..
For example, are you creating an upgrade to your own program ? That is, do you have access to the source code ? If you do, then you only need to implement the new functionalities, rebuild the program files and distribute them in a small installation.
If, however, you are planning to create an upgrade to some one else's program, to which you don't have any source code available, I heavily suggest that you first contact the author of the software and either ask him/her to implement the new functionalities, or request for a source code portion to implement these functionalities yourself. The first option is of course the more polite one, as not all authors are willing to hand over their source codes, especially if they are commercial products.
The final option is to outrightly hack the program. This means that you would first reverse-engineer the original executable (disassemble it), then do the necessary changes in assemblic code. Needless to say that this is extremely difficult and I suggest you do not even try it out, as you might ruin the program file if you don't know what you're doing.
There are no sites or resources that I am aware which would handle this type of issue, as mostly upgrades or patches are created and released by those people who originally made the software. I suggest you contact the author and ask him/her for an opinion of what to do.
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
I'm really sorry for the lack of information...
And yes, I'm planning to upgrade my own program. I'm not sure whether I should create new installation program for distribution as it requires uninstallation of the old version (which has very small modification in it for the upgrade). What's more, I want the registry settings for the program to remain as it is before upgrade.
That's why I thought patching would be the best method to get this done. I know I can easily create a patch using readily available patch generator program but I'd really like to build it on my own.
Though, I'm really clueless on what are the tools I need and what I'm required to do...
Tried getting the msimsp.exe file as suggested in msdn but there's no available installation for xp.
Really appreciate your help and thanks again....
|
|
|
|
|
In MDI environment, I want to create a toolbar window that will be displayed at the startup. (much like the main toolbar window in abode photoshop) What's the best way to do this?
|
|
|
|
|
/*********************************************************************/
/***************WINDOWS SOCKET代理服务器******************************/
/***************Email:tujj99@hotmail.com******************************/
/***************程序还有很多问题,欢迎讨论****************************/
/*********************************************************************/
#include <winsock2.h>
//#include <windows.h>
#include <stdio.h>
//#include <conio.h>
#define SERVER_PORT 4040 /*服务端口 */
#define PROXY_PORT 8080
#define MSG_SIZE 8192 /*缓冲区的大小 */
#define MAX_THREAD 1000
//#define SERVER_NAME_MAX_SIZE 256
#define BACKLOG 5 /*等待服务的最大数*/
char server_addr[]="172.17.1.39";
char proxy_addr[]="130.1.201.81";
int server_port = SERVER_PORT;
int proxy_port = PROXY_PORT;
int thread_no;
struct sockaddr_in pro_addr;
SOCKET hostserver;
unsigned long thID;
typedef struct tClientIP_
{
char ip[16];
unsigned short port;
SOCKET cli_socket;
int reserve;
}tClientIP;
/****************************************************************/
/* NAME : InitServer */
/* IN : NULL */
/* OUT : 1/0 Success/Failure */
/* Sumary: 初始化服务器 */
/****************************************************************/
int InitServer()
{
struct sockaddr_in ser_addr; /* 服务器的地址 */
WSADATA WSAData;
int addrlen,errorno;
thread_no = 0;
//init WSA
if(WSAStartup(MAKEWORD(2,2),&WSAData)){
printf("WSA start error!");
return -1;
}
/*创建连接的SOCKET */
hostserver = socket(AF_INET,SOCK_STREAM,0);
if(hostserver == INVALID_SOCKET){/*创建失败 */
errorno = WSAGetLastError();
printf("socker Error:%d\n",errorno);
WSACleanup();
return -1;
}
else{
// printf("Server socket creating successfully!\n");
}
/*初始化服务器地址*/
addrlen=sizeof(struct sockaddr_in);
ZeroMemory(&ser_addr,addrlen);
ser_addr.sin_family=AF_INET;
ser_addr.sin_addr.s_addr=htonl(INADDR_ANY); //任何主机都可以访问
ser_addr.sin_port=htons(server_port);
if(bind(hostserver,(struct sockaddr *)&ser_addr,sizeof(ser_addr)) == SOCKET_ERROR){/*绑定失败 */
errorno = WSAGetLastError();
printf("Bind Error:%d\n",errorno);
closesocket(hostserver);
WSACleanup();
return -1;
}
else{
printf("bind socket to successfully!\n");
}
/*侦听客户端请求*/
if(listen(hostserver,SOMAXCONN) == SOCKET_ERROR ){
errorno = WSAGetLastError();
printf("Listen Error:%d\n",errorno);
closesocket(hostserver);
WSACleanup();
return -1;
}
else{
printf("Start listening on %s:%d....\n",server_addr,server_port);
}
/* 初始化代理服务器地址*/
addrlen=sizeof(struct sockaddr_in);
ZeroMemory(&pro_addr,addrlen);
pro_addr.sin_family=AF_INET;
pro_addr.sin_addr.s_addr=inet_addr(proxy_addr);
pro_addr.sin_port=htons(proxy_port);
return 0;
}
/*****************************************************************/
/* NAME : ServerThread */
/* IN : LPVOID lpParam */
/* OUT : DWORD */
/* Sumary: 服务器接受一条消息,然后发送到代理server, */
/* 再接收从代理server返回的数据,再送往client */
/*****************************************************************/
DWORD WINAPI ServerThread(LPVOID lpParam)
{
int n; /* 接受到的或发送的数据的字节数*/
// ret; /* select()返回值 */
char msg[MSG_SIZE]; /* 缓冲区*/
SOCKET cli_socket, /* 客户端SOCKET */
pro_socket; /* Proxy SOCKET */
tClientIP ClientIP;
int errorno;
// fd_set fdread;
// fd_set fdwrite;
ClientIP = *(reinterpret_cast<tclientip *="">(lpParam));
cli_socket = ClientIP.cli_socket;
if(cli_socket == INVALID_SOCKET)
{
printf("client socket error!\n");
ExitThread(0);
}
/* 客户端IP+端口 */
//printf("Request from %s:%d\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port));
printf("begin thread %d....\n",GetCurrentThreadId());
/* 创建一个新Proxy socket */
pro_socket = socket(AF_INET,SOCK_STREAM,0);
if(pro_socket == INVALID_SOCKET){/*创建失败 */
errorno = WSAGetLastError();
printf("socker Error:%d\n",errorno);
thread_no --;
closesocket(cli_socket);
ExitThread(0);
}
else{
//printf("Proxy socket:%d creating successfully!\n",pro_socket);
}
int t = 2000;
if(setsockopt(pro_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof(t)) == SOCKET_ERROR)
{
errorno = WSAGetLastError();
printf("Set socket option Error:%d\n",errorno);
}
/* 请求连接代理服务器 */
if(connect(pro_socket,(struct sockaddr *)&pro_addr,sizeof(pro_addr)) == SOCKET_ERROR){
errorno = WSAGetLastError();
printf("Listen Error:%d\n",errorno);
thread_no --;
closesocket(pro_socket);
closesocket(cli_socket);
ExitThread(0);
}
// FD_ZERO(&fdread);
// FD_SET(cli_socket, &fdread);
// ret =select(NULL, &fdread, NULL, NULL, NULL);
// if(ret == SOCKET_ERROR)
// {
// printf("select error!%d\n",WSAGetLastError());
// closesocket(cli_socket);
// ExitThread(0);
// }
// if(FD_ISSET(cli_socket, &fdread)) {
while(1)
{
/* 接收客户端消息 */
ZeroMemory(msg,sizeof(msg));
n = recv(cli_socket,msg,MSG_SIZE,0);
if( n > 0){
printf("[%d]:C[%-16s:%-5d] >> S[%-16s:%-5d] [%d]\n",
GetCurrentThreadId(),ClientIP.ip,ClientIP.port,server_addr,server_port,n);
}
else if(n == 0) {
printf("client connection closed!\n");
break;
}
else if(n == SOCKET_ERROR){
errorno = WSAGetLastError();
printf("client socket closed or error:%d\n",errorno);
break;
}
// }
// FD_ZERO(&fdwrite);
// FD_SET(pro_socket, &fdwrite);
// ret = select(NULL, NULL, &fdwrite, NULL, NULL);
// if(ret == SOCKET_ERROR)
// {
// printf("select error!%d\n",WSAGetLastError());
// closesocket(cli_socket);
// ExitThread(0);
// }
// if(FD_ISSET(pro_socket, &fdwrite)) {
/* 转发消息到代理服务器*/
n = send(pro_socket,msg,n,0);
if( n > 0) {
// printf("[%d]:To Proxy ----> [%d]\n",GetCurrentThreadId(),n);
printf("[%d]:S[%-16s:%-5d] >> P[%-16s:%-5d] [%d]\n",
GetCurrentThreadId(),server_addr,server_port,proxy_addr,proxy_port,n);
}
else if(n == SOCKET_ERROR) {
errorno = WSAGetLastError();
printf("SEND TO PROXY ERROR:%d\n",errorno);
break;
}
// }
while(1)
{
// FD_ZERO(&fdread);
// FD_SET(pro_socket, &fdread);
// ret = select(NULL, &fdread, NULL, NULL, NULL);
// if(ret == SOCKET_ERROR)
// {
// printf("select error!%d\n",WSAGetLastError());
// closesocket(cli_socket);
// ExitThread(0);
// }
// if(FD_ISSET(pro_socket, &fdread)) {
/* 从代理服务器接收消息*/
ZeroMemory(msg,sizeof(msg));
n = recv(pro_socket,msg,MSG_SIZE,0);
if( n > 0){
// printf("[%d]:From Proxy <---- [%d]\n",GetCurrentThreadId(),n);
printf("[%d]:S[%-16s:%-5d] << P[%-16s:%-5d] [%d]\n",
GetCurrentThreadId(),server_addr,server_port,proxy_addr,proxy_port,n);
}
else if(n == 0) {
break;
}
else if(n == SOCKET_ERROR){
errorno = WSAGetLastError();
printf("client socket closed or error:%d\n",errorno);
break;
}
// }
// FD_ZERO(&fdwrite);
// FD_SET(cli_socket, &fdwrite);
// ret = select(NULL, NULL, &fdwrite, NULL, NULL);
// if(ret == SOCKET_ERROR)
// {
// printf("select error!%d\n",WSAGetLastError());
// closesocket(cli_socket);
// ExitThread(0);
// }
// if(FD_ISSET(cli_socket, &fdwrite)) {
/* 返回数据给客户端 */
n = send(cli_socket,msg,n,0);
if( n > 0){
// printf("[%d]:To Client ----> [%d]\n",GetCurrentThreadId(),n);
printf("[%d]:C[%-16s:%-5d] << S[%-16s:%-5d] [%d]\n",
GetCurrentThreadId(),ClientIP.ip,ClientIP.port,server_addr,server_port,n);
}
else if(n == SOCKET_ERROR){
errorno = WSAGetLastError();
printf("client socket closed or error:%d\n",errorno);
break;
}
}
}
closesocket(pro_socket);
closesocket(cli_socket);
thread_no --;
printf("exit thread [%d]....\n",GetCurrentThreadId());
return 1;
}
/*****************************************************************/
/* NAME : ListenThread */
/* IN : LPVOID lpParam */
/* OUT : DWORD */
/* Sumary: 处理客户请求的线程 */
/*****************************************************************/
DWORD WINAPI ListenThread(LPVOID lpParam)
{
int addrlen,errorno;
HANDLE hThread[MAX_THREAD];
SOCKET client; /* 客户端SOCKET */
struct sockaddr_in cli_addr; /* 客户端的地址 */
tClientIP ClientIP;
addrlen = sizeof(cli_addr);
while(1)
{
ZeroMemory(&cli_addr,sizeof(cli_addr));
/* 等待接收客户连接请求 */
client = accept(hostserver,(struct sockaddr*)&cli_addr,&addrlen);
/* 获取客户端临时端口 */
strcpy(ClientIP.ip , inet_ntoa(cli_addr.sin_addr));
ClientIP.port = cli_addr.sin_port;
ClientIP.cli_socket = client;
/* 开启服务线程 */
hThread[thread_no] = CreateThread(
NULL, //缺省的安全性
0, //缺省的堆栈
ServerThread, //线程入口
reinterpret_cast<lpvoid>(&ClientIP), //客户端socket
0, //无特殊创建标志
&thID); //返回线程的ID
if(hThread[thread_no] == NULL){
errorno = WSAGetLastError();
printf("thread create error! %d\n",errorno);
closesocket(ClientIP.cli_socket);
}
else{
thread_no++;
}
}
}
/****************************************************************/
/* NAME : main */
/* IN : NULL */
/* OUT : NULL */
/* Sumary: 入口程序(创建监听线程) */
/****************************************************************/
void main()
{
HANDLE hListen;
int errorno;
/* 初始化服务器 */
if(InitServer() < 0){
/* 初始化失败 */
errorno = GetLastError();
printf("Init error:%d",errorno);
ExitProcess(0);
}
/* 创建监听线程 */
hListen = CreateThread(
NULL, //缺省的安全性
0, //缺省的堆栈
ListenThread, //监听线程入口
NULL, //
0, //无特殊创建标志
&thID); //返回线程的ID
if(hListen = NULL)
{
/* 创建线程失败 */
errorno = WSAGetLastError();
printf("thread create error! %d\n",errorno);
WSACleanup();
ExitProcess(0);
}
// ::WaitForSingleObject(hListen,INFINITE);
Sleep(999999);
closesocket(hostserver);
WSACleanup();
}
////////////////////////////////////////////////////////////////////////////
//lots of problems , can u ?
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
Hi!
I have installed libpcap to my linux computer, and I have made a simple program that uses the file pcap.h in /include.
I having problem with looking up the device. My code is:
dev = pcap_lookupdev(errbuf);
and message I get when I compile is
/home/steve/tmp/ccCzGEwY.o(.text+0x1e): In function `main':
: undefined reference to `pcap_lookupdev'
collect2: ld returned 1 exit status
Can someone help me??
Thanks for your time
/Stefan
|
|
|
|
|
This just means that the function 'pcap_lookupdev' is not defined properly. Either it is missing from the header file or you don't have the actual implementation of the function.
Did you remember to install any accompanied library files as well ? Remembered to include those libraries to the build/compile phase ?
-Antti Keskinen
----------------------------------------------
The definition of impossible is strictly dependant
on what we think is possible.
|
|
|
|
|
You need to add -lpcap to your compile options, and ensure that libpcap.o is in a place that can be found by the compiler (either in the path specified by the LIB environment variable, or add the path using the -L option, IIRC).
|
|
|
|
|