求助WINSOCK。客户端如何持续发送消息到服务端。

王晓蛮 2014-09-28 10:49:09

这里是server的代码。


int main(int argc, char* argv[])
{
// 这里监听的SOCKET
SOCKET listenServer;
SOCKADDR_IN listenAddr,clientAddr;
int err,errcode;

WSADATA wsData;
WSAStartup(MAKEWORD(2,2), &wsData);

listenServer = socket(AF_INET, SOCK_STREAM, 0);
listenAddr.sin_family = AF_INET;
listenAddr.sin_port = htons(8056);
listenAddr.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listenServer,(SOCKADDR*)&listenAddr, sizeof(SOCKADDR_IN));
err = listen(listenServer,5);

if(SOCKET_ERROR == err) {
//cout<<WSAGetLastError()<<endl;
}

cout << "服务器已经启动,等待客户端连接..." <<endl;
char buff[MAX_PATH];
while(TRUE)
{
int len = sizeof(clientAddr);
SOCKET client = accept(listenServer,(SOCKADDR*)&clientAddr,&len);
// buff = "发送内容";

recv(client,buff,strlen(buff),0);
cout<<"从"<<inet_ntoa(clientAddr.sin_addr)<<"来的消息:"<<buff << endl;
}
closesocket(listenServer);
WSACleanup();
return 0;
}



这里是client的代码


int main(int argc, char* argv[])
{
int err,errcode;
SOCKADDR_IN listenAddr;
WSADATA wsData;
WSAStartup(MAKEWORD(2,2), &wsData);
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);

listenAddr.sin_family = AF_INET;
listenAddr.sin_port = htons(8056);
listenAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.128");

err = connect(clientSocket,(SOCKADDR*)&listenAddr,sizeof(SOCKADDR));

if(err == SOCKET_ERROR) {
cout << WSAGetLastError()<<endl;
}
//while(TRUE)
//{
char buff[MAX_PATH];
sprintf(buff,"这里内容");
send(clientSocket,buff,strlen(buff)+1,0);
//}
closesocket(clientSocket);
WSACleanup();
return 0;
}



这里是问题~~~,代码是没有问题的,可以正常的接收到消息 ,并显示出来
1. 我想客户端持续向服务端发送消息 ,比如:我想一次向服务端发送10个消息,并且消息的内容不一样。 ,如何实现。(运行10次客户端,)
2. 客户端如何把指定的BITMAP发送到服务端。。。


来个大神解惑。。
...全文
267 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿呆_ 2014-09-28
  • 打赏
  • 举报
回复
引用 8 楼 xviphackl 的回复:

    ......

// 线程函数
DWORD WINAPI threadFunc(LPVOID p)
{
	uSOCKETPARAM *usp = (uSOCKETPARAM*)p;
	char buff[MAX_PATH];
	while(1){
		recv(usp->s,buff,strlen(buff),0);
		cout<<"从"<<inet_ntoa(usp->addr.sin_addr)<<"来的消息:"<<buff << endl;
	}
	return 0;
}
......
recv(usp->s,buff,strlen(buff),0); ??? 新手的通病:不知道strlen()是什么意思。 没错,它是取长度,但是它只能取以'\0'结尾的字符串长度。 你char buff[MAX_PATH];定义后凭什么认定buff[0..MAX_PATH-2]为非0而恰巧buff[MAX_PATH-1] == '\0' ?
王晓蛮 2014-09-28
  • 打赏
  • 举报
回复
引用 2 楼 xian_wwq 的回复:
[quote=引用 楼主 xviphackl 的回复:] 这里是问题~~~,代码是没有问题的,可以正常的接收到消息 ,并显示出来 1. 我想客户端持续向服务端发送消息 ,比如:我想一次向服务端发送10个消息,并且消息的内容不一样。 ,如何实现。(运行10次客户端,) 2. 客户端如何把指定的BITMAP发送到服务端。。。 来个大神解惑。。
示例中的Server写的太简易, 客户端连接后,即server端accept后获取的socket 要被保存下来,这样就可以完成后续的处理。 accept后数据处理必须启用新的工作线程, 在工作线程中循环recv就可以获取该socket的数据。 对于client端,处理很简单,只要socket连接成功后, 发送什么数据都是调用send方法[/quote] ///////////////////////////////////////////////////////////////////////////////////////////////////// @xian_wwq 大神,看我新改的代码。有如下问题。 1.客户是可以持续向服务端发送消息 ,但是,服务端接收不到消息 。 2.有时候客户端的程序可能直接死掉。 ///////////////////////////////////////////////////////////////////////////////////////////////////// 服务端的代码

        /**
          在头文件中的一个struct
          struct uSOCKETPARAM{
	              SOCKET s;
	              SOCKADDR_IN addr;
         };
        */
	uSOCKETPARAM *usp = new uSOCKETPARAM;
	while(TRUE)
	{
		int len = sizeof(clientAddr);
		SOCKET client = accept(listenServer,(SOCKADDR*)&clientAddr,&len);
	//	buff = "发送内容";
		usp->s = client;
		usp->addr = clientAddr;
		CloseHandle(
			CreateThread(NULL,0,threadFunc,(LPVOID)usp,0,0)
		);
	/*	recv(client,buff,strlen(buff),0);
		cout<<"从"<<inet_ntoa(clientAddr.sin_addr)<<"来的消息:"<<buff << endl;*/
	}

// 线程函数
DWORD WINAPI threadFunc(LPVOID p)
{
	uSOCKETPARAM *usp = (uSOCKETPARAM*)p;
	char buff[MAX_PATH];
	while(1){
		recv(usp->s,buff,strlen(buff),0);
		cout<<"从"<<inet_ntoa(usp->addr.sin_addr)<<"来的消息:"<<buff << endl;
	}
	return 0;
}
客户端的代码。

	while(TRUE)
	{
	char buff[MAX_PATH];
		sprintf(buff,"这里内容");
		send(clientSocket,buff,strlen(buff)+1,0);
	}
xian_wwq 2014-09-28
  • 打赏
  • 举报
回复
引用 6 楼 xviphackl 的回复:
[quote=引用 3 楼 xian_wwq 的回复:] 对于socket来说,它不去人发的是bitmap还是MP3 它只负责处理byte[],至于数据如何解析,完全是业务层的处理; 还有1楼赵老师提示的重点是tcp“粘包“,这是构建tcpserver需要考虑
非常感谢!!!不过没有懂,。。。。。。。[/quote] 谁都是从不懂到懂,先读《windows 网络编程》
王晓蛮 2014-09-28
  • 打赏
  • 举报
回复
引用 3 楼 xian_wwq 的回复:
对于socket来说,它不去人发的是bitmap还是MP3 它只负责处理byte[],至于数据如何解析,完全是业务层的处理; 还有1楼赵老师提示的重点是tcp“粘包“,这是构建tcpserver需要考虑
非常感谢!!!不过没有懂,。。。。。。。
王晓蛮 2014-09-28
  • 打赏
  • 举报
回复
引用 2 楼 xian_wwq 的回复:
[quote=引用 楼主 xviphackl 的回复:] 这里是server的代码。

int main(int argc, char* argv[])
{
	// 这里监听的SOCKET
	SOCKET listenServer;
	SOCKADDR_IN listenAddr,clientAddr;
	int err,errcode;

	WSADATA wsData;
	WSAStartup(MAKEWORD(2,2), &wsData);
	
	listenServer = socket(AF_INET, SOCK_STREAM, 0);
	listenAddr.sin_family = AF_INET;
	listenAddr.sin_port = htons(8056);
	listenAddr.sin_addr.S_un.S_addr = INADDR_ANY;
	bind(listenServer,(SOCKADDR*)&listenAddr, sizeof(SOCKADDR_IN));
	err = listen(listenServer,5);

	if(SOCKET_ERROR == err) {
		//cout<<WSAGetLastError()<<endl;
	}
	
	cout << "服务器已经启动,等待客户端连接..." <<endl;
	char buff[MAX_PATH];
	while(TRUE)
	{
		int len = sizeof(clientAddr);
		SOCKET client = accept(listenServer,(SOCKADDR*)&clientAddr,&len);
	//	buff = "发送内容";

		recv(client,buff,strlen(buff),0);
		cout<<"从"<<inet_ntoa(clientAddr.sin_addr)<<"来的消息:"<<buff << endl;
	}
	closesocket(listenServer);
	WSACleanup();
	return 0;
}
这里是client的代码

int main(int argc, char* argv[])
{
	int err,errcode;
	SOCKADDR_IN listenAddr;
	WSADATA wsData;
	WSAStartup(MAKEWORD(2,2), &wsData);
	SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);

	listenAddr.sin_family = AF_INET;
	listenAddr.sin_port = htons(8056);
	listenAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.128");

	err = connect(clientSocket,(SOCKADDR*)&listenAddr,sizeof(SOCKADDR));

	if(err == SOCKET_ERROR) {
		cout << WSAGetLastError()<<endl;
	}
	//while(TRUE)
	//{
	char buff[MAX_PATH];
		sprintf(buff,"这里内容");
		send(clientSocket,buff,strlen(buff)+1,0);
	//}
	closesocket(clientSocket);
	WSACleanup();
	return 0;
}
这里是问题~~~,代码是没有问题的,可以正常的接收到消息 ,并显示出来 1. 我想客户端持续向服务端发送消息 ,比如:我想一次向服务端发送10个消息,并且消息的内容不一样。 ,如何实现。(运行10次客户端,) 2. 客户端如何把指定的BITMAP发送到服务端。。。 来个大神解惑。。
示例中的Server写的太简易, 客户端连接后,即server端accept后获取的socket 要被保存下来,这样就可以完成后续的处理。 accept后数据处理必须启用新的工作线程, 在工作线程中循环recv就可以获取该socket的数据。 对于client端,处理很简单,只要socket连接成功后, 发送什么数据都是调用send方法[/quote] 非常感谢您的解答!!!我在试试,有不懂的话,在请教大家。
王晓蛮 2014-09-28
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
感谢老师,的回答,不过,我是新手有点不懂!!说得太高深了。
xian_wwq 2014-09-28
  • 打赏
  • 举报
回复
对于socket来说,它不去人发的是bitmap还是MP3 它只负责处理byte[],至于数据如何解析,完全是业务层的处理; 还有1楼赵老师提示的重点是tcp“粘包“,这是构建tcpserver需要考虑
xian_wwq 2014-09-28
  • 打赏
  • 举报
回复
引用 楼主 xviphackl 的回复:
这里是server的代码。

int main(int argc, char* argv[])
{
	// 这里监听的SOCKET
	SOCKET listenServer;
	SOCKADDR_IN listenAddr,clientAddr;
	int err,errcode;

	WSADATA wsData;
	WSAStartup(MAKEWORD(2,2), &wsData);
	
	listenServer = socket(AF_INET, SOCK_STREAM, 0);
	listenAddr.sin_family = AF_INET;
	listenAddr.sin_port = htons(8056);
	listenAddr.sin_addr.S_un.S_addr = INADDR_ANY;
	bind(listenServer,(SOCKADDR*)&listenAddr, sizeof(SOCKADDR_IN));
	err = listen(listenServer,5);

	if(SOCKET_ERROR == err) {
		//cout<<WSAGetLastError()<<endl;
	}
	
	cout << "服务器已经启动,等待客户端连接..." <<endl;
	char buff[MAX_PATH];
	while(TRUE)
	{
		int len = sizeof(clientAddr);
		SOCKET client = accept(listenServer,(SOCKADDR*)&clientAddr,&len);
	//	buff = "发送内容";

		recv(client,buff,strlen(buff),0);
		cout<<"从"<<inet_ntoa(clientAddr.sin_addr)<<"来的消息:"<<buff << endl;
	}
	closesocket(listenServer);
	WSACleanup();
	return 0;
}
这里是client的代码

int main(int argc, char* argv[])
{
	int err,errcode;
	SOCKADDR_IN listenAddr;
	WSADATA wsData;
	WSAStartup(MAKEWORD(2,2), &wsData);
	SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);

	listenAddr.sin_family = AF_INET;
	listenAddr.sin_port = htons(8056);
	listenAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.128");

	err = connect(clientSocket,(SOCKADDR*)&listenAddr,sizeof(SOCKADDR));

	if(err == SOCKET_ERROR) {
		cout << WSAGetLastError()<<endl;
	}
	//while(TRUE)
	//{
	char buff[MAX_PATH];
		sprintf(buff,"这里内容");
		send(clientSocket,buff,strlen(buff)+1,0);
	//}
	closesocket(clientSocket);
	WSACleanup();
	return 0;
}
这里是问题~~~,代码是没有问题的,可以正常的接收到消息 ,并显示出来 1. 我想客户端持续向服务端发送消息 ,比如:我想一次向服务端发送10个消息,并且消息的内容不一样。 ,如何实现。(运行10次客户端,) 2. 客户端如何把指定的BITMAP发送到服务端。。。 来个大神解惑。。
示例中的Server写的太简易, 客户端连接后,即server端accept后获取的socket 要被保存下来,这样就可以完成后续的处理。 accept后数据处理必须启用新的工作线程, 在工作线程中循环recv就可以获取该socket的数据。 对于client端,处理很简单,只要socket连接成功后, 发送什么数据都是调用send方法
赵4老师 2014-09-28
  • 打赏
  • 举报
回复
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
王晓蛮 2014-09-28
  • 打赏
  • 举报
回复
引用 13 楼 xian_wwq 的回复:
http://blog.csdn.net/woshinia/article/details/8585930
Thanks,OK。明白了,结算了。
xian_wwq 2014-09-28
  • 打赏
  • 举报
回复
http://blog.csdn.net/woshinia/article/details/8585930
王晓蛮 2014-09-28
  • 打赏
  • 举报
回复
引用 11 楼 xian_wwq 的回复:
1. while中没有sleep是不对的,表象就是程序死了 2. 一个客户端一个线程测试可以,工程应用不行,看看 windows socket 五种IO模型 3.客户端关闭后,socket就会异常,这时候server端就需要对异常进行处理, 退出线程的处理代码在哪里呢? server端不会智能退出死循环
‘ 嗯,我知道,如果,客户端,退出,服务端就应该抛出异常。但是,这个抛出异常的代码写在线程里面,如何。写。。有点不没有明白的。可以给一个简单的例子。 Thanks。
xian_wwq 2014-09-28
  • 打赏
  • 举报
回复
1. while中没有sleep是不对的,表象就是程序死了 2. 一个客户端一个线程测试可以,工程应用不行,看看 windows socket 五种IO模型 3.客户端关闭后,socket就会异常,这时候server端就需要对异常进行处理, 退出线程的处理代码在哪里呢? server端不会智能退出死循环
王晓蛮 2014-09-28
  • 打赏
  • 举报
回复
引用 9 楼 Idle_ 的回复:
[quote=引用 8 楼 xviphackl 的回复:]

    ......

// 线程函数
DWORD WINAPI threadFunc(LPVOID p)
{
	uSOCKETPARAM *usp = (uSOCKETPARAM*)p;
	char buff[MAX_PATH];
	while(1){
		recv(usp->s,buff,strlen(buff),0);
		cout<<"从"<<inet_ntoa(usp->addr.sin_addr)<<"来的消息:"<<buff << endl;
	}
	return 0;
}
......
recv(usp->s,buff,strlen(buff),0); ??? 新手的通病:不知道strlen()是什么意思。 没错,它是取长度,但是它只能取以'\0'结尾的字符串长度。 你char buff[MAX_PATH];定义后凭什么认定buff[0..MAX_PATH-2]为非0而恰巧buff[MAX_PATH-1] == '\0' ? [/quote] OK,这个问题解决了。但是,又有一个新的问题来了。。。 就是我把客户端的程序关闭了,服务端还在继续打印消息。。。【概念】有点模糊,应该是服务端中的程序应该控制如果客户端退出了,就应该释放线程。。。。。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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