下面的这段程序是一个winsock的多线程的例子。方法可能很土,还请大家指点。
我先在服务器上开一个socket用来listen,用来支持最多10个客户的连接,如下,我用了一个循环,一旦accept一个连接之后,就用CreateThread建立一个线程,用来处理该连接上数据的收发等问题。
我定义了线程函数DWORD WINAPI ThreadFunc(LPVOID pvParam)
线程函数里面的参数类型LPVOID好象是固定的,然后我想通过该参数把accept产生的socket传递过去。
于是我用如下方法:
sAccepted[iAccepted] = accept(srv, \
(sockaddr *)&addr_accept[iAccepted],&iAddrLen); CreateThread(NULL,0,ThreadFunc, \
(LPVOID)sAccepted[iAccepted],0,lpThread);
程序运行到此就出现访问未知内存错误了。请大家指点,另外大家能否提供利用多线程支持多客户的更好的方法,消息机制或怎么样的?用个循环感觉是太土了。
#include "stdafx.h"
#include "winsock.h"DWORD WINAPI ThreadFunc(LPVOID pvParam);int main(int argc, char* argv[])
{
SOCKET srv;
WSADATA wsd; WSAStartup(MAKEWORD(1,1),&wsd);
srv = socket(AF_INET,SOCK_STREAM,0); sockaddr_in srv_addr;
srv_addr.sin_family = AF_INET;
srv_addr.sin_addr.S_un.S_addr = inet_addr("10.40.59.88");
srv_addr.sin_port = htons(8080); bind(srv,(sockaddr *)&srv_addr,sizeof(sockaddr_in));
listen(srv,10); SOCKET sAccepted[10];
sockaddr_in addr_accept[10];
LPDWORD lpThread;
int iAccepted = 0;
int iAddrLen;
iAddrLen = sizeof(sockaddr_in);
while (iAccepted < 10)
{
sAccepted[iAccepted] = accept(srv, \
(sockaddr *)&addr_accept[iAccepted],&iAddrLen); CreateThread(NULL,0,ThreadFunc, \
(LPVOID)sAccepted[iAccepted],0,lpThread);
iAccepted++;
} return 0;
}DWORD WINAPI ThreadFunc(LPVOID pvParam)
{
DWORD dwResult = 0;
SOCKET s;
s=(SOCKET)pvParam; char *strBuf = new char[1000];
recv(s,strBuf,sizeof(strBuf),0);
return dwResult;
}
我先在服务器上开一个socket用来listen,用来支持最多10个客户的连接,如下,我用了一个循环,一旦accept一个连接之后,就用CreateThread建立一个线程,用来处理该连接上数据的收发等问题。
我定义了线程函数DWORD WINAPI ThreadFunc(LPVOID pvParam)
线程函数里面的参数类型LPVOID好象是固定的,然后我想通过该参数把accept产生的socket传递过去。
于是我用如下方法:
sAccepted[iAccepted] = accept(srv, \
(sockaddr *)&addr_accept[iAccepted],&iAddrLen); CreateThread(NULL,0,ThreadFunc, \
(LPVOID)sAccepted[iAccepted],0,lpThread);
程序运行到此就出现访问未知内存错误了。请大家指点,另外大家能否提供利用多线程支持多客户的更好的方法,消息机制或怎么样的?用个循环感觉是太土了。
#include "stdafx.h"
#include "winsock.h"DWORD WINAPI ThreadFunc(LPVOID pvParam);int main(int argc, char* argv[])
{
SOCKET srv;
WSADATA wsd; WSAStartup(MAKEWORD(1,1),&wsd);
srv = socket(AF_INET,SOCK_STREAM,0); sockaddr_in srv_addr;
srv_addr.sin_family = AF_INET;
srv_addr.sin_addr.S_un.S_addr = inet_addr("10.40.59.88");
srv_addr.sin_port = htons(8080); bind(srv,(sockaddr *)&srv_addr,sizeof(sockaddr_in));
listen(srv,10); SOCKET sAccepted[10];
sockaddr_in addr_accept[10];
LPDWORD lpThread;
int iAccepted = 0;
int iAddrLen;
iAddrLen = sizeof(sockaddr_in);
while (iAccepted < 10)
{
sAccepted[iAccepted] = accept(srv, \
(sockaddr *)&addr_accept[iAccepted],&iAddrLen); CreateThread(NULL,0,ThreadFunc, \
(LPVOID)sAccepted[iAccepted],0,lpThread);
iAccepted++;
} return 0;
}DWORD WINAPI ThreadFunc(LPVOID pvParam)
{
DWORD dwResult = 0;
SOCKET s;
s=(SOCKET)pvParam; char *strBuf = new char[1000];
recv(s,strBuf,sizeof(strBuf),0);
return dwResult;
}
解决方案 »
- 动态修改工具栏及状态栏的提示
- 为什么Win7下管理员权限运行程序SentMessage和postMessage拒绝访问?
- 请问windowless的MFC ActiveX怎么处理消息?
- 一个简单的问题。
- [★{☆ 求救 ☆}★] 热切希望有DLL注入编程经验的朋友帮我解决这个难题。。
- 使用Access写入字符串时为什么他要帮我添加不必要的空格?一定会这样吗?
- 屏幕抓图后,如何存为灰度图像?
- 据说,用SOCKET创建原始套接字,并把网卡设置成“混杂摸式”,就能捕捉到所有从网卡进来的原始网络数据包,恳请各位高手指点指点,哪怕是提供一些相关资料!!
- COleDateTime 问题
- 在哪儿设置datagrid的列数?我找了半天也没找到,气死了!!!
- 如何替代win2000的messager服务来接收信息?
- 请问vc中能否不创建数据源就连接数据库呀?象vb那样
这是个局部变量,传到线程函数里去岂不糟糕?另外推荐你用非阻塞模式下的socket...有4种I/O模型可供选择。
最简单的方法莫过于从CAsyncSocket派生一个类,重载
OnAccept, OnRecieve, OnSend, OnClose等函数,这个类本身就
包装的异步socket,用的事件模式,对于一般的小型应用足够。
如果要求很高,就用I/O完成端口模型好了
(sockaddr *)&addr_accept[iAccepted],&iAddrLen); CreateThread(NULL,0,ThreadFunc, \
(LPVOID)sAccepted[iAccepted],0,lpThread);改为:
SOCKET s;s = accept(srv, (sockaddr *)&addr_accept[iAccepted],&iAddrLen);
sAccepted[iAccepted] = s;
CreateThread(NULL,0,ThreadFunc, \
(LPVOID)&s,0,lpThread);
用Detach()从socket中分离SOCKET传到接收线程中,用Attach()附加到生成的socket中就不会出错了,有问题QQ;39446783
livelivelive(神仙般的生活) ( )
我在单位只能通过sockxp上QQ,速度太慢,加了几次未成功。我有点疑问。socket在BSD中好象其实也就是个int型的数字,来代表一个socket。
如int s=socket(.....)
在Winsock里面,SOCKET是不是已经不是int了,而是一个结构?
{
sAccepted[iAccepted] = accept(srv, \
(sockaddr *)&addr_accept[iAccepted],&iAddrLen);
if(sAccepted[iAccepted]=INVALID_SOCKET;//这句话好我加的
continue; CreateThread(NULL,0,ThreadFunc, \
(LPVOID)sAccepted[iAccepted],0,lpThread);
iAccepted++;
}