首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

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

2013-04-21 
C SOCKET 服务器端如何支持多路收发?#pragma comment(lib,wsock32.lib)#include stdio.h#include win

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函数调用?

个人呢表示不理解。

热点排行