Socket一个问题请教

sc_valentine21 2009-03-13 05:04:47

//CClientConn.cpp TCP/IP方式
//创建Socket
BOOL CClientConn::Create()
{
m_socket = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == m_socket)
{
AfxMessageBox(L"创建失败!");
return FALSE;
}
socket1 = m_socket;//socket1是一个全局变量,用于保存创建的socket
SOCKET *pSocket = &m_socket;
//创建一个接收数据的线程,参数传入已创建的Socket
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (LPVOID)pSocket, 0, NULL);
if (m_hRecvThread)
{
CloseHandle(m_hRecvThread);
}
return TRUE;
}
//连接
BOOL CClientConn::Connect()
{
SOCKADDR_IN address;
int len = sizeof(address);
address.sin_family = AF_INET;
address.sin_port = htons(60000);
address.sin_addr.S_un.S_addr = inet_addr("192.168.1.106");//本地IP
int n = connect(m_socket, (SOCKADDR *)&address, len);
if (SOCKET_ERROR == n)
{
AfxMessageBox(L"连接失败");
closesocket(m_socket);
return FALSE;
}
return TRUE;
}
//接收线程
DWORD CClientConn::RecvThreadProc(LPVOID lpParameter)
{
SOCKET *pSocket= (SOCKET *)lpParameter;//将传递进来的参数转换
while (TRUE)
{
char recvBuf[100];
memset(recvBuf, 0, sizeof(recvBuf));
int result = recv(*pSocket/*socket1*/, recvBuf, sizeof(recvBuf), 0);
//问题就出在这里,如果用全局变量socket1就没有问题,
//但是用我传进来的pSocket就不行,一直都是SOCKET_ERROR,不知道什么原因。
TRACE(L"%s\n", CString(recvBuf));
if (SOCKET_ERROR == result)
{
//int err = WSAGetLastError();
AfxMessageBox(L"接收失败");
return FALSE;
}
else if(result > 0)
{
//转宽字符
//1.确定转换为Unicode需要多少缓冲区(返回值也包含了最后一个NULL字符)。
int nLen = MultiByteToWideChar(CP_ACP, 0, recvBuf, -1, NULL, 0);
//2.定义一个临时变量,分配内存
WCHAR *tempBuf = new WCHAR[nLen];
//3.转换
MultiByteToWideChar(CP_ACP, 0, recvBuf, -1, tempBuf, nLen);
//给CString赋值
CString string = tempBuf;
if (tempBuf)
{
delete []tempBuf;
tempBuf = NULL;
}
AfxMessageBox(string);
}
else if (result == 0)
{
AfxMessageBox(L"连接已断开");
break;
}
}
return 0;
}
...全文
161 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
sc_valentine21 2009-03-14
  • 打赏
  • 举报
回复
谢谢
sc_valentine21 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 arong1234 的回复:]
楼主有几个非常坏的习惯
1. 字符串都用L"ABC"形式声明,这样如果你切换编译模式,你所有的代码都必须重新修改。正确的时用_T("abc")代替L"abc"
2. 遇到所有的错误,你都只打印错误信息,而不打印错误原因。如果遇到错误,你啥信息都得不到
3. 用AfxMessageBox报告错误,尤其再线程内部是个非常坏的习惯
[/Quote]
一直以来都是自己写程序,没有规范,很多方面做得是很不好
看得出来,你是经验老道之人了,有一些规范啊什么的,不妨指点一下小弟。
在此不甚感激。
arong1234 2009-03-13
  • 打赏
  • 举报
回复
对于单参数情况,没有必要这样做。你这样做和他用SOCKET*似乎没有什么额外的不同,就多一层结构而已。当且仅当你有多个参数需要传递才需要这么做
这里他不传指针,只传socket才是最优的,否则在线程内部必须额外删除不属于他分配的指针

[Quote=引用 12 楼 zjl_1026_2001 的回复:]

呵呵 楼主最好不要这样用吧,你创建线程并传递参数时最好将参数放到一个结构体里面,比如这样

struct strMyPara
{
SOCKET sock;
};

strMyPara my_para;
my_para.sock = m_socket;

//创建一个接收数据的线程,参数传入已创建的Socket
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (void*)pSocket, 0, NULL);

然后在线程函数中再做转换就可以了

strMyPara* p_my_para = (strMyPara*)…
[/Quote]
sc_valentine21 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zjl_1026_2001 的回复:]

呵呵 楼主最好不要这样用吧,你创建线程并传递参数时最好将参数放到一个结构体里面,比如这样

struct strMyPara
{
SOCKET sock;
};

strMyPara my_para;
my_para.sock = m_socket;

//创建一个接收数据的线程,参数传入已创建的Socket
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (void*)pSocket, 0, NULL);

然后在线程函数中再做转换就可以了

strMyPara* p_my_para = (strMyPara*)…
[/Quote]
恩,值得深思。那么做也许更好
sc_valentine21 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 arong1234 的回复:]
这是一种更好的解决方法,但是不是原因,因为你再线程函数内也把它当指针用的,你用*pSocket在线程函数内也不能当指针用了
最关键的原因是你的指针会指向一个临时变量,这才是关键
引用 6 楼 sc_valentine21 的回复:
找到问题了。谢谢

C/C++ code
//参数传错了,*pSocket才是等同于m_socket;
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (LPVOID)*pSocket, 0, NULL);
[/Quote]
恩,你说的我明白了,只是我pSocket指向的是类的成员变量所以没有报错,如果是临时变量就会报错了。
houzui 2009-03-13
  • 打赏
  • 举报
回复
SOCKET *pSocket= (SOCKET *)lpParameter;//将传递进来的参数转换
感觉应该是上面这行代码的问题,没准pSocket还等于空呢,调试下看看。
沙漠里的海豚 2009-03-13
  • 打赏
  • 举报
回复

呵呵 楼主最好不要这样用吧,你创建线程并传递参数时最好将参数放到一个结构体里面,比如这样

struct strMyPara
{
SOCKET sock;
};

strMyPara my_para;
my_para.sock = m_socket;

//创建一个接收数据的线程,参数传入已创建的Socket
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (void*)pSocket, 0, NULL);

然后在线程函数中再做转换就可以了

strMyPara* p_my_para = (strMyPara*)lpParameter;//将传递进来的参数转换
int result = recvp_my_para->sock, recvBuf, sizeof(recvBuf), 0);



sc_valentine21 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 arong1234 的回复:]
楼主有几个非常坏的习惯
1. 字符串都用L"ABC"形式声明,这样如果你切换编译模式,你所有的代码都必须重新修改。正确的时用_T("abc")代替L"abc"
2. 遇到所有的错误,你都只打印错误信息,而不打印错误原因。如果遇到错误,你啥信息都得不到
3. 用AfxMessageBox报告错误,尤其再线程内部是个非常坏的习惯
[/Quote]
感谢,获益良多
arong1234 2009-03-13
  • 打赏
  • 举报
回复
这是一种更好的解决方法,但是不是原因,因为你再线程函数内也把它当指针用的,你用*pSocket在线程函数内也不能当指针用了
最关键的原因是你的指针会指向一个临时变量,这才是关键
[Quote=引用 6 楼 sc_valentine21 的回复:]
找到问题了。谢谢

C/C++ code
//参数传错了,*pSocket才是等同于m_socket;
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (LPVOID)*pSocket, 0, NULL);
[/Quote]
太乙 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sc_valentine21 的回复:]
找到问题了。谢谢

C/C++ code
//参数传错了,*pSocket才是等同于m_socket;
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (LPVOID)*pSocket, 0, NULL);
[/Quote]那你这就带复制了哈!而不是传递本身哦~~
arong1234 2009-03-13
  • 打赏
  • 举报
回复
楼主有几个非常坏的习惯
1. 字符串都用L"ABC"形式声明,这样如果你切换编译模式,你所有的代码都必须重新修改。正确的时用_T("abc")代替L"abc"
2. 遇到所有的错误,你都只打印错误信息,而不打印错误原因。如果遇到错误,你啥信息都得不到
3. 用AfxMessageBox报告错误,尤其再线程内部是个非常坏的习惯
太乙 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 arong1234 的回复:]
注意子线程可能会在创建它的函数结束时再执行,很显然,你传进去的是一个临时变量的指针,当你那个recv线程开始执行时,那个变量早不存在了
正确的方法


C/C++ code
SOCKET *pSocket = new SOCKET;
*pSocket = m_socket;
//创建一个接收数据的线程,参数传入已创建的Socket
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (LPVOID)pSocket, 0, NULL);





注意在RecvThreadProc里…
[/Quote]up@!
sc_valentine21 2009-03-13
  • 打赏
  • 举报
回复
找到问题了。谢谢

//参数传错了,*pSocket才是等同于m_socket;
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (LPVOID)*pSocket, 0, NULL);
arong1234 2009-03-13
  • 打赏
  • 举报
回复
注意子线程可能会在创建它的函数结束时再执行,很显然,你传进去的是一个临时变量的指针,当你那个recv线程开始执行时,那个变量早不存在了
正确的方法


SOCKET *pSocket = new SOCKET;
*pSocket = m_socket;
//创建一个接收数据的线程,参数传入已创建的Socket
m_hRecvThread = CreateThread(NULL, 0, RecvThreadProc, (LPVOID)pSocket, 0, NULL);



注意在RecvThreadProc里你需要delete这个内存
逸萌 2009-03-13
  • 打赏
  • 举报
回复
比较*pSocket、 socket1是否相同,或者pSocket == &socket1

如果相同则没有问题,不同的话可能是代码中不小心改变了

仔细审查代码!
sc_valentine21 2009-03-13
  • 打赏
  • 举报
回复
是一样的

SOCKET socket1;
//全局变量是这么定义的

感觉应该没得问题,有点摸不着头脑
  • 打赏
  • 举报
回复
int result = recv(*pSocket/*socket1*/, recvBuf, sizeof(recvBuf), 0);
//问题就出在这里,如果用全局变量socket1就没有问题,
//但是用我传进来的pSocket就不行,一直都是SOCKET_ERROR,不知道什么原因。
pSocket跟socket1的数据类型不一样吧,SOCKET *pSocket= (SOCKET *)lpParameter;//这个强制转换的问题?
sc_valentine21 2009-03-13
  • 打赏
  • 举报
回复

int result = recv(*pSocket/*socket1*/, recvBuf, sizeof(recvBuf), 0);
//问题就出在这里,如果用全局变量socket1就没有问题,
//但是用我传进来的pSocket就不行,一直都是SOCKET_ERROR,不知道什么原因。

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧