读书人

C SOCKET 服务器端怎么支持多路收发

发布时间: 2013-04-21 21:18:07 作者: rapoo

C SOCKET 服务器端如何支持多路收发?


#pragma comment(lib,"wsock32.lib")
#include <stdio.h>
#include <winsock2.h>
#include <winsock2.h>

#define SERVER_PORT 5208 //侦听端口

void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int ret, nLeft, length;

SOCKET sListen, sServer; //侦听套接字,连接套接字
struct sockaddr_in saServer, saClient; //地址信息

char receiveMessage[1024],sendMessage[1024];
int i,L;


//WinSock初始化
wVersionRequested=MAKEWORD(2, 2); //希望使用的WinSock DLL 的版本
ret=WSAStartup(wVersionRequested, &wsaData);
if(ret!=0)
{
printf("WSAStartup() failed!\n");
return;
}
//创建Socket,使用TCP协议
sListen=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sListen == INVALID_SOCKET)
{
WSACleanup();
printf("socket() faild!\n");
return;
}
//构建本地地址信息
saServer.sin_family = AF_INET; //地址家族
saServer.sin_port = htons(SERVER_PORT); //注意转化为网络字节序
saServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //使用INADDR_ANY 指示任意地址

//绑定
ret = bind(sListen, (struct sockaddr *)&saServer, sizeof(saServer));
if (ret == SOCKET_ERROR)
{
printf("bind() faild! code:%d\n", WSAGetLastError());
closesocket(sListen); //关闭套接字
WSACleanup();
return;
}

//侦听连接请求
ret = listen(sListen, 5);
if (ret == SOCKET_ERROR)
{
printf("listen() faild! code:%d\n", WSAGetLastError());
closesocket(sListen); //关闭套接字
return;
}

printf("Waiting for client connecting!\n");
printf("Tips: Ctrl+c to quit!\n");
//阻塞等待接受客户端连接
while(1)//循环监听客户端,永远不停止,所以,在本项目中,我们没有心跳包。
{
length = sizeof(saClient);
sServer = accept(sListen, (struct sockaddr *)&saClient, &length);
if (sServer == INVALID_SOCKET)
{
printf("accept() faild! code:%d\n", WSAGetLastError());
closesocket(sListen); //关闭套接字
WSACleanup();
return;


}

nLeft = sizeof(receiveMessage);
printf("nleft Length:%d",nLeft);

while(nLeft>0)
{
//接收数据
ret = recv(sServer, receiveMessage, 1024, 0);
printf("ret Length:%d",ret);
if (ret == SOCKET_ERROR)
{
printf("recv() failed!\n");
return;
}
if (ret == 0) //客户端已经关闭连接
{
printf("Client has closed the connection\n");
break;
}

L=strlen(receiveMessage);
printf("ReciveData Length:%d",L);
printf("ReciveData:");
for(i=0;i<ret;i++)
{
printf("%02X",(receiveMessage[i]&0xff));
}

sendMessage[0]=0x31;
sendMessage[1]=0x32;
ret=send(sServer,sendMessage,2,0);
printf("send length:%d\n",ret);
printf("\n");
}

}
// closesocket(sListen);
// closesocket(sServer);
// WSACleanup();
}


上面是服务器端代码,单路,也就一对一的收发没有问题

下面图是,用调试软件,开了两个,分别连接服务器端,均可以连接上

但是,开启了 2810 端口,和 2824 端口的两个调试终端,只有一个可以与服务器端完成交互

即2810先连接时,服务器只与开启该端口的终端交互数据。 2824虽然也能连上,但是发送数据后,无法收到服务器端返回的数据...

同样,2824先连接上时,服务器则只与2824 这个交互数据。2810 则无法交互,能发但是不能收...


C SOCKET 服务器端怎么支持多路收发


请教,服务器端要如何修改?才能与客户端一对一的完成交互?
即,多个客户端同时连接服务器时,哪个客户端发送数据来,就将数据原路返回给该客户端...

谢谢

[解决办法]
while(1)
{...
sServer = accept(sListen, (struct sockaddr *)&saClient, &length);
...}
sServer是服务端接收链接后创建出来的新的套接字,有多少个终端就有多少个套接字接过来。简单处理的话,你可以用一个数组将各个有效的sServer保存起来,然后用select模型监测套接字的状态,哪个有数据就读,读完以后就回复

[解决办法]
http://www.baidu.com/link?url=oWkFGJqjJ4zBBpC8yDF8xDhdujWhB6sfDWMUakoCM2qu2ktxVCongtZ-L8GmpjrO3YWRAIvva6K

windows网络编程 第二版 第六章 IOCP有源码, 实现的就是这个功能
[解决办法]
select 模型

或者CPP/CPT 即accept到一个client就开一个进程/线程。然后在进程/线程里面处理收发
[解决办法]
VC6:
工程、设置、C/C++、分类:Preprocessor、附加包含路径:填写附加头文件所在目录 逗号间隔多项
工程、设置、Link、分类:Input、附加库路径:填写附加依赖库所在目录 分号间隔多项
工程、设置、Link、分类:Input、对象/库模块:填写附加依赖库的名字.lib 空格间隔多项
VS20xx:
项目、属性、C/C++、附加包含目录:填写附加头文件所在目录 分号间隔多项
项目、属性、链接器、附加库目录:填写附加依赖库所在目录 分号间隔多项
项目、属性、链接器(点前面的+展开)、输入、附加依赖项:填写附加依赖库的名字.lib 空格间隔多项

[解决办法]
我看了半天,没找到线程创建?也没找到select函数调用?

个人呢表示不理解。

读书人网 >C语言

热点推荐