多线程的问题不用考虑,一个CLIENT端像SERVER发数据,SERVER端接收数据虽然是多线程的,但是可以用一个线程写数据,这样就没问题了。其实作为DBMS应该直接由解决以上问题的机制,不知ACCESS有没有,我想应该是有的。
解决方案 »
- VC编码转化
- 求教,如何绘制菜单成两栏,即两行
- 郁闷的call into BHO
- 100分,在CView中接收无模式对话框发来的消息,为什么在调试(Debug)状态下可以,而在Release中报错?
- listctrl如何编辑内容。还有我怎么像EXCEL一样,插入一行或一列?
- (送分)关于编译环境vc++6 (dev) 打开ResoureView时提示关于afxres.h等的错误。
- 小送20分------------头文件有没有长度限制!
- 做图形处理需要那些基础知识
- 读数据库的数据出错
- 我的VC为什么不能自动注册控件,注册时就没有反应?高分求教高手!快帮帮我!
- 有没有人能解答,怎样获得正在运行的窗口的进程标志???
- 请问高手,如何在IE浏览器中嵌入一个图标,像安装了金山毒霸后就会出现一个金山毒霸的图标。
在vc中没做过,vb里好像是不好使,有时候写的快了都出问题
我对这方面不是很清楚,所以可不可以写一下代码?主要部分就可以了
比如什么时候CREATE,什么时候CONNECT什么时候CLOSE,还有多线程的代码 麻烦你们了 [email protected]
我会再新开个帖子的,有400分
我这有个SERVER的模型:
//serverdoc.h
CTypedPtrList<CPtrList,CClientSocket *> m_SocketList;//客户端请求Socket列表
listensocket *m_plisten;//serverdoc.cpp
serverdoc::OnNewDocument()
{
m_plisten->Create(nBasicPort,SOCK_STREAM);
m_pListen->Listen();
}//listensocket.cpp
listensocket::OnAccept()
{
...
CClientSocket * pSocket = new CClientSocket;
pDoc->m_pListen->Accept(*pSocket);
pSocket->AsyncSelect(FD_READ|FD_CLOSE);
pDoc->m_SocketList.AddTail(pSocket);
...
}
...
关于多线程的同步控制可以参见MSDN
时候可以给出相关代码啊?我对这方面不是很熟悉
[email protected]
(我假设你是由各机把数据送到服务器,由服务程序再写入数据库。)
2。插入数据库的时候最好采用SQL语句(INSERT 。)。(为了解决可移植)
3。服务器程序要采用线程同步。(保证不会出错)
4。(可选的)可以为服务器程序先分配一个缓冲区,用于先存放接收到的临时数据,然后在插入到数据库中。(解决收到的数据远比插入的要快)
--------------------------------------------------------------------------------------------------------------------------
注意点,必须要使用线程同步,否则会出现不可预料的错误。
Access的Shared功能可以支持多人同时访问。
当然,用SQL Server或Oracle会好一点。
#include "stdafx.h"
#include <conio.h>
#include <Winsock2.h>
#include "service.h"
#include <fstream.h>DWORD WINAPI TcpThread(LPVOID lpParam)
{
SOCKET sock=(SOCKET)lpParam;
char szBuffer[BUFFER_SIZE];
int ret;
while(1)
{
ret = recv(sock, szBuffer, BUFFER_SIZE, 0);
if (ret == 0)
{
printf("Disconnected, thread terminated\n");
printf("------------------------------------------------------------\n");
closesocket(sock);
break;
}
else if(ret == SOCKET_ERROR && WSAECONNRESET != WSAGetLastError())
{
printf("Recieve failed, Error number: %d \n", WSAGetLastError());
printf("------------------------------------------------------------\n");
closesocket(sock);
break;
}
}
return 0;
}DWORD WINAPI ListenTcp(LPVOID plstnport)
{
WSADATA wsd;
SOCKET sListen, sClient;
int iAddrSize;
HANDLE hThread;
DWORD dwThreadID;
struct sockaddr_in local, client;
char logfile[20];
__u16 lstnport;
lstnport = *(__u16*)plstnport; sprintf(logfile, "tcplog-%d.log", lstnport); if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("Failed to load Winsock!\n");
return 0;
} sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if(sListen == SOCKET_ERROR)
{
printf("ListenTcp()::Socket() failed, Error number: %d \n", WSAGetLastError());
return 0;
} local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(lstnport); if(bind(sListen, (struct sockaddr *)&local, sizeof(local))==SOCKET_ERROR)
{
printf("ListenTcp::bind() faided, Error number: %d \n", WSAGetLastError());
return 1;
} listen(sListen, 10); ofstream of(logfile); while(1)
{
iAddrSize = sizeof(client); sClient = accept(sListen, (struct sockaddr *)&client, &iAddrSize);
if(sClient == INVALID_SOCKET)
{
printf("ListenTcp::accept() failed, Error number: %d \n", WSAGetLastError());
break;
} char op = 1; int Err = setsockopt(
sClient,
SOL_SOCKET,
SO_DONTLINGER,
(char*)&op,
sizeof(op)
); hThread = CreateThread(NULL, 0, TcpThread,
(LPVOID)sClient, 0, &dwThreadID); if(hThread == NULL)
{
printf("CreateThread(TcpThread()) failed, Error number: %d \n", GetLastError());
break;
} printf("Accepted: [%s]:[%d] -> [%d] \n",
inet_ntoa(client.sin_addr), ntohs(client.sin_port),
ntohs(local.sin_port)); printf("------------------------------------------------------------\n"); of << "Accepted: [" << inet_ntoa(client.sin_addr) << "]:["
<< ntohs(client.sin_port) << "] -> [" << ntohs(local.sin_port) <<
"]" << endl; of << "------------------------------------------------------------" << endl; CloseHandle(hThread);
} closesocket(sListen);
WSACleanup();
return 1;
}这段代码每接受一个客户端的连接,就会在一个log文件里记下客户端的IP和端口号,你改改就可以用了。
CRITICAL_SECTION g_csAccess; //定义为全局的
InitializeCriticalSection (&g_csAccess); //在启动的时候先初始化//此函数相当于多线程中的同时访问数据库的部分
void AccessDB()
{
EnterCriticalSection (&g_csAccess); //在每次访问数据库的部分加上// 在这里写加入访问数据库的代码LeaveCriticalSection (&g_csAccess); //访问完之后加上
}
DeleteCriticalSection (&g_csAccess); //关闭程序的时候,把对象删除