TCP套接字
TCP套接字实现过程:实现TCP套接字基本步骤分为服务器端和客户端两部分。
1、服务器端步骤
(1)创建套接字
(2)绑定套接字
(3)设置套接字为监听模式,进入被动接受连接请求状态。
(4)接受请求、建立连接
(5)读/写数据
(6)终止连接
2、客户端步骤
(1)创建套接字
(2)与远程服务程序连接
(3)读/写数据
(4)终止连接
如下图:

TCP 服务器模板
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
main()
{
int sockfd,connect_sock;
/*Create TCP socket*/
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) = = -1)
{
perror(“Creating socket failed.”);
exit(1);
}
/*Bind socket to address*/
/*listen client`s regirement*/
….
loop
{
/*accept connection*/
if((connect_sock = accept(sockfd,NULL,NULL)) = = -1)
{
perror(“Acception failed.”);
exit(1);
}
/*Creat child process or thread to service clients*/
….
}
}
TCP客户端模板
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
main()
{
int sockfd;
/*Create TCP socket*/
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror(“Createint socket failed.”);
exit(1);
}
/*Connect to server and receive data from the server*/
……
}
实现 TCP 套接字
一、产生TCP套接字
1、socket函数原型
#include <sys/types.h>
#include <sys/socket.h>
int socket (int domain, int type, int protocol );
2、函数描述
创建一个套接字,并为套接字数据结构分配存储空间。
domain:协议簇和地址簇,确定socket使用的一组协议。与以下三个符号常数有关。
PF_UNIX:Unix系统内部协议
PF_INET:IP版本4
PF_INET6:IP版本6
type:通信类型,相关常数如下。
SOCK_STREAM:以字节形式通信,面向连接的协议使用这种形式。
SOCK_DGRAM:数据以独立的数据包形式流动,无连接协议使用这种形式。
SOCK_RAW:是低于传输层的低级协议或物理网络提供的套接字类型。它可以访问内部网络接口。
protocol:指明此socket请求所使用的协议,可以使用如下相关符号常数来表示。
IPPROTO_TCP:表示TCP协议。
IPPROTO_UDP:表示UDP协议。
返回值:
如果调用成功,返回socket描述符,否则返回-1。
二、绑定
1、bind函数原型
#include <sys/types.h>
#include <sys/socket.h>
int bind ( int s ,const struct sockaddr *name, int namelen );
2、描述
s 是套接字描述符,套接字函数返回的套接字描述符。
Name 是本地套接字地址,是指向特定套接字地址结构的指针,指定用于通信的本地协议端口。
Namelen 是本地套接字地址结构的长度。
三、监听
1、listen 函数原型
#include <sys/types.h>
#include <sys/socket.h>
int listen (int s ,int backlog);
2、描述
listen()为申请进入的连接建立输入数据队列,将到达本地的客户服务连接请求保存在此队列上,直到程序处理它们为止。
s 是套接字系统调用返回的套接字描述符;
backlog 指定在请求队列中允许的最大请求数。进入的连接请求将在队列中等待accept()函数处理它们。backlog对阶列中等待服务请求的数目进行了限制。 如果一个服务请求到来时,输入队列已满,该套接字将拒绝连接请求,客户将收到一个出错信息。
四、接受请求
1、accept 函数原型
#include <sys/types.h>
#include <sys/socket.h>
int accept(int s, struct sockaddr *addr,socklen_t *addrlen);
2、描述
s是被监听的socket描述符。
addr通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求)。
addrlen通常为一个指向值为sizeof(struct sockaddr_in)的整型指针变量。
五、建立连接
1、connect 函数原型
#include <sys/types.h>
#include <sys/socket.h>
int connect(int s,const struct sockaddr *name,int namelen);
2、描述
s 是 socket()函数返回的套接字描述符。
name 是包含远程主机IP地址和端口号的指针。
namelen 是远程地址结构的长度。
六、数据传输
1、send 函数原型
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send (int s,const void *msg,size_t len,int flags);
2、描述
s 是你想用来传输数据的socket描述符;msg是一个指向要发送数据的指针;len是以字节为单位的数据的长度;flags是传输控制标志,一般情况下 置为0(0:常规操作,如write();)
3、返回值
调用成功返回发送数据的长度(以字节为单位),否则返回-1。
4、recv 函数原型
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv ( int s,void *buf,size_t len,int flags);
5、描述
s是接受数据的socket描述符;buf 是存放接收数据的缓冲区;len是缓冲的长度。flags也被置为0。
6、返回值
调用成功返回接收数据的长度(以字节为单位),否则返回-1并置相应的errno值。当对方关闭连接时,返回的接收数据长度为0。通常以此来判断对方是否 关闭。
七、终止连接
close函数原型
close(sockfd);
你也可以调用shutdown()函数来关闭该socket。该函数允许你只停止在某个方向上的数据传输,而一个方向上的数据传输继续进行。如你可以关闭 某socket的写操作而允许继续在该socket上接受数据,直至读入所有数据。
转自http://www.bestlinux.cn/emb/wdtec/linuxnetwork/tcpsocket.html