免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1528 | 回复: 3
打印 上一主题 下一主题

[C] 请教一个网络编程的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-07 23:42 |只看该作者 |倒序浏览
目的:
建立一个tcp server,使用select多路复用处理用户新建连接以及以及建立的连接的数据读操作

思路:
1.建立server socket
2.把server socket加入select的读数组
3.客户端建立的连接加入select的读数组
4.处理新的连接以及以及建立的连接的数据

代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <netinet/in.h> // struct sockaddr_in

#include <sys/select.h> // select()


#define SERVER_PORT 3361
#define BUFF_SIZE 512
#define MAX_TCP_CONNECTION 10

int main()
{
  int ServerFd, ClientFd[MAX_TCP_CONNECTION];
  int ClientAddrLen, Bytes, MaxClientIndex=0, i;
  struct sockaddr_in ServerAddr, ClientAddr;
  char Buf[BUFF_SIZE];
  fd_set readset;

  ServerFd = socket(AF_INET, SOCK_STREAM, 0);

  memset(&ServerAddr, 0, sizeof(struct sockaddr_in));
  ServerAddr.sin_family = AF_INET;
  ServerAddr.sin_port = htons(SERVER_PORT);
  ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  bind (ServerFd, (struct sockaddr*)&ServerAddr, sizeof(struct sockaddr));

  listen(ServerFd, 5);

  while(1)
  {
    FD_ZERO(&readset);
    FD_SET(ServerFd, &readset);
    for(i=0;i<MaxClientIndex;i++)
      FD_SET(ClientFd[i], &readset);
    if (MaxClientIndex)
      select(ClientFd[MaxClientIndex]+1, &readset, NULL, NULL, NULL);
    else
      select(ServerFd+1, &readset, NULL, NULL, NULL);
    if (FD_ISSET(ServerFd, &readset))
    {
      ClientFd[MaxClientIndex] = accept(ServerFd, (struct sockaddr*)&ClientAddr, &ClientAddrLen);
      printf("Ah, new connection < %d 0x%.8x:%d > established!\n", ClientFd[MaxClientIndex], ClientAddr.sin_addr.s_addr, ClientAddr.sin_port);
      MaxClientIndex++;
      printf("MAX Connection: %d\n", MaxClientIndex);
    }
    else
    {
      for(i=0;i<MaxClientIndex;i++)
      {
        if (!FD_ISSET(ClientFd[i], &readset))
          continue;
        Bytes = read(ClientFd[i], Buf, BUFF_SIZE-1);
        if (Bytes<=0)
          continue;
        Buf[Bytes] = '\0';
        printf("CONNECTION(%d) %s", ClientFd[i], Buf);
      }
    }

  }

  close(ServerFd);

  return 0;
}


现象:
客户端可以建立到服务器的连接,但是以及建立连接的客户端发送的数据服务器端收不到,使用gdb调试发现阻塞在select调用没有返回。

问题:
如何处理accept还要处理read操作,谢谢。

论坛徽章:
0
2 [报告]
发表于 2009-12-08 00:22 |只看该作者
accept(ServerFd, (struct sockaddr*)&ClientAddr, &ClientAddrLen);

这里没猜错的话,返回的应该是 -1 。原因是参数错误。
另外 没有检查 select 的返回值, 由于中断原因会返回-1的。
maxfd +1 明显不是简单 ClientFd[MaxClientIndex]+1,  除非你打算永远不关闭套接字。

论坛徽章:
0
3 [报告]
发表于 2009-12-08 23:21 |只看该作者
accept之后MaxClientIndex=1,而这时ClientFd[MaxClientIndex]+1是多少呢?
是ClientFd[1]+1
ClientFd[1]是多少呢,虽然你没有初始化,但是0的概率还是蛮大的
select(0+1, &readset, NULL, NULL, NULL);结果是相当于检测标准输入了
虽然你的程序还有其他问题,但就你疑惑的问题来说,使用ClientFd[MaxClientIndex-1]而不是ClientFd[MaxClientIndex]应该是正解

[ 本帖最后由 ssh210 于 2009-12-8 23:24 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-12-09 10:32 |只看该作者
我觉得这程序的逻辑咋这乱。。。

[ 本帖最后由 wuexp 于 2009-12-9 10:44 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP