windows TCP socket在C++下的编程入门 5

来源:互联网 发布:mmd镜头数据怎么导入 编辑:程序博客网 时间:2024/05/17 03:52

接收连接-作为服务器发出这个动作

       现在你对连接远程电脑有了一点感觉了吧,现在让我们谈谈服务器所扮演的角色。我们知道远程电脑能够连接你,为了做这个,我们能够监听任何端口和等待到来的连接,一如既往的,我们使用一些API句柄调用;

     int PASCAL bind(SOCKET,const sruct sockaddr*,int );//绑定sock

    int PASCAL listen(SOCKET,int);//监听到来的连接

 //接收一个连接要求

 SOCKET PASCAL accept(SOCKET,struct sockaddr*,int *);

  当你作为一个服务器动作,你能够接收你所监听的端口的连接请求,例如,一个远程的电脑想要和你交谈,首先它要问你的服务器需要或者不需要建立连接,为了连接能够建立连接,你的服务器必须 accept() 这个连接要求,注意 server 决定要不要建立连接,最终,双方电脑都被连接了以及能够交换数据。

 虽然 listen()函数是最简单的监听端口的方法,作为服务器,它并不是最令人满意的,你会很快发现当你试图使用它你的程序将会假死掉直到到来的连接被建立,因为listen()是一个阻塞函数,它一次只能执行一个任务,它不会返回直到一个连接被建立。

  这绝对是一个问题,但是有几个方法可以解决,首先,如果你熟悉多线程编程(注意,我们在这里不讨论TCP线程),然后你能够把你的服务代码放入单独的线程,当开始的时候,将不会死掉整个程序并且主程序也不会被阻碍,但这真的是浪费功夫,你只需要用 asynchronous sockets代替 listen() 函数,如果我已经用那个听起来很重要名字吸引了你的注意,你可以跳过接下来的章节,但是我建立你跟着我并且学习好基础。我们在以后会完善我们的代码,但是现在,让我们集中于主要的东西。

   在你考虑监听端口之前你必须

   1,初始化 Winsock (我们之前讨论过的,记得吗)

   2 , 开始一个socket并且确保他不返回一个空值,这意味着成功了以及指向这个socket的句柄,

   3 ,用必须的数据填充 SOCKADDR_IN(),   包括地址家族,端口和IP地址。

   4    使用bind()来绑定socket到一个具体的IP地址(如果你指定inet_addr("0.0.0.0")或者htonl(INADDR_ANY)作为SOCKADDR_IN的sin_addr部分,你能够绑定任何IP地址)

这时候,如果所以都按照计划进行,你们全都将准备调用 listen()以及转向主内容。

 

    listen()函数的第一个形式参数必须是指向你前面初始化的socket的句柄,当然,无论这个socket端口连接到什么它都是你将要监听的端口,然后你能指定下一个或者最后一个参数,你的服务器能同时与多少台远程电脑交流,一般来讲,然而除非你想要排序所有的只想建立很少的几个连接,我们传递SOMAXCONN(SOcket MAX CONNEction)作为listen()的最后的参数,如果这个socket工作正常,所有的都应该正常,当收到一个连接请求时,listen()将被返回,如果你想要建立一个连接那么这个返回值就是你调用aeecpt()函数的线索。

  #include<windows.h>

 #include<winsock.h>

 SOCKET s;

 WSADATA w;

 //LTSTENONPORT-为到来的连接监听一个具体的端口或者数据

int ListenOnPort(int portion)

 {

   int error=WSAStartup(0x0202,&w); //填写 WSA信息

  if(error)

   {

     return false; //因为一些原因我们不能开始winsock

   }

   if (w.WVersion!=0x0202) //winsock的版本错了

    {

     WSACleanup();

     return false;

  }

  SOCKADDR_IN addr; //TCP socket的地址结构

addr.sin_family=AF_INET; //地址家族

addr.sin_port=htons(porton);//将端口赋值给这个socket

//使用 INADDR_ANY来接受一个来自任何IP的连接

//你能够传递内部地址("0.0.0.0")来代替完成同样的事,如果你只想注意来自一个指定的IP连接请求specify that//instead.

addr.sin_addr.s_addr = htonl (INADDR_ANY);

s = socket (AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建 socket

if( s== INVALID_SOCKET)

 {

   return  false;//在我们不能创建一个socket成功的时候不要继续

}

 if( bind(s,(LPSOCKADDR)&addr,sizeof(addr))==SOCKET_ERROR)

 {

  //不能绑定(这在我们试图多次绑定一些socket的时候可能发生

  return false;

}

// 现在我们可以开始监听(使用 SOMAXCONN 允许尽可能多的连接在同一时间被建立)我们为了客户目的能够指定任何等于或者小于SOMAXCONN值的整数,这个函数在有一个连接要求建立之前将不会返回

listen(s,SOMAXCONN);

//不要忘记用CLoseConnection()函数清除!

}

如果你编译并且运行这些代码,正如在前面提到的,你的程序将冻结直到连接要求被建立,你能够建立这个连接要求,例如,尝试一个" telnet" 连接,这个连接将不可避免的失败,当然,因为这个连接将不会被接受但是,你将能够使得 listen() 函数返回 并且你的程序将重新活过来从冻结中,你能够尝试这个通过在MSDOS命令提示符使用 telnet  127.0.0.1 端口数字(用你的服务监听的端口数字代替给出的端口数字).

0 0
原创粉丝点击