socket 编程入门教程(一)TCP server 端:7、接收与发送

现在,我们通过accept()创建了新的socket,也就是我们类中的数据成员communicationSock,现在,我们就可以通过这个socket进行通讯了。

TCP通讯模型

        在介绍函数之前,我们应该了解一些事实。TCP的Server/Client模型类似这样:
ServApp——ServSock——Internet——ClntSock——ClntApp
当然,我们这里的socket指的就是用于“通讯”的socket。TCP的server端至少有两个socket,一个用于监听,一个用于通讯;TCP的client端可以只有一个socket,这个socket同时“插”在server的两个socket上。当然,插上listen socket的目的只是为了创建communication socket,创建完备后,listen是可以关闭的。但是,如果这样,其他的client就无法再连接上server了。
        我们这个模型,是client的socket插在server的communication socket上的示意。这两个socket,都拥有完整的本地地址信息以及远程计算机地址信息,所以,这两个socket以及之间的网络实际上形成了一条形式上“封闭”的管道。数据包只要从一端进来,就能知道出去的目的地,反之亦然。这正是TCP协议,数据流形式抽象化以及实现。因为不再需要指明“出处”和“去向”,对这样的socket(实际上是S/C上的socket对)的操作,就如同对本地文件描述符的操作一样。但是,尽管我们可以使用read()和write(),但是,为了完美的控制,我们最好使用recv()和send()。

recv()和send()

int  send( int  socket,  const   void *  msg, unsigned  int  msgLength,  int  flags);
int  recv( int  socket,  void *  rcvBuffer, unsigned  int  bufferLength,  int  flags);

在Linux中的实现为:

#include  < sys / socket.h >

/*  Send N bytes of BUF to socket FD.  Returns the number sent or -1.

   This function is a cancellation point and therefore not marked with
   __THROW.  
*/
extern  ssize_t send ( int  __fd, __const  void   * __buf, size_t __n,  int  __flags);

/*  Read N bytes into BUF from socket FD.
   Returns the number read or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  
*/
extern  ssize_t recv ( int  __fd,  void   * __buf, size_t __n,  int  __flags);

这两个函数的第一个参数是用于“通讯”的socket,第二个参数是发送或者接收数据的起始点指针,第三个参数是数据长度,第四个参数是控制符号(默认属性设置为0就可以了)。失败时候传回-1,否则传回实际发送或者接收数据的大小,返回0往往意味着连接断开了。

处理echo行为

void  TcpServer::handleEcho()
{
    
const   int  BUFFERSIZE  =   32 ;
    
char  buffer[BUFFERSIZE];
    
int  recvMsgSize;
    
bool  goon  =   true ;

    
while  ( goon  ==   true  ) {
        
if  ( (recvMsgSize  =  recv(communicationSock, buffer, BUFFERSIZE,  0 ))  <   0  ) {
            
throw   " recv() failed " ;
        } 
else   if  ( recvMsgSize  ==   0  ) {
            goon 
=   false ;
        } 
else  {
            
if  ( send(communicationSock, buffer, recvMsgSize,  0 !=  recvMsgSize ) {
                
throw   " send() failed " ;
            }
        }
    }

    close(communicationSock);
}

本小节最后要讲的函数是close(),它包含在<unistd.h>中

#include  < unistd.h >

/*  Close the file descriptor FD.

   This function is a cancellation point and therefore not marked with
   __THROW.  
*/
extern   int  close ( int  __fd);

这个函数用于关闭一个文件描述符,自然,也就可以用于关闭socket。
下一小节是完整的源代码。默认的监听端口是5000。我们可以通过
$telnet 127.0.0.1 5000
验证在本机运行的echo server程序。

转载于:https://www.cnblogs.com/yin-jingyu/archive/2012/06/06/2537558.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值