您的位置:首页 > 理论基础 > 计算机网络

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

2012-06-06 03:35 726 查看
现在,我们通过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程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐