TCP-网络编程-实现一个TCP Server

本文介绍了TCP网络编程中的关键步骤,包括使用socket创建连接、bind绑定IP和端口、listen监听请求、connect客户端连接、accept建立连接以及read/write、recv/send等读写操作。同时,详细解析了socket接口的使用,并给出了TCP Server的实现代码。
摘要由CSDN通过智能技术生成

1. socket

网络层中的IP地址可以唯一确定一台主机,而传输层的 协议+端口 可以唯一表示主机中的应用程序(进程),因此利用三元组(Ip 地址,协议,端口)就可以表示网络中的进程。

进程间的通信是通过socket来完成的,socket类似于文件操作,封装了一组接口,利用这些接口完成**“打开、读/写、关闭操作”**

以TCP协议通信的socket为例,下图是TCP的交互过程:
在这里插入图片描述

具体过程如下:
(1)服务器根据地址类型( ipv4, ipv6 )、 socket 类型、协议创建 socket
(2)bind(): 服务器为 socket 绑定 IP 地址和端口号
(3)listen(): 服务器监听端口号请求,随时接受客户端发来的链接请求,此时,服务器的socket并没有打开
(4)客户端创建socket
(5)connect(): 客户端打开socket,并根据服务器的IP地址和端口号尝试链接服务器socket
(6)accept(): 服务器监听到客户端的socket请求,被动打开socket,开始接收客户端请求,此时,服务端socket进入阻塞状态,即accept()方法,直到客户端返回连接信息(三次握手过程)后才返回。
(7)客户端连接成功,向服务器发送连接状态信息
(8)服务器accept()方法返回,连接成功
(9)send(): 客户端向socket写入信息
(10)recv(): 服务端读取信息
(11)客户端关闭
(12)服务器端关闭

2. 接口详解

(1)socket函数

函数原型: int socket(int domain , int type , int protocol) ;

返回值:整型的socket描述符。 socket函数对应于普通的文件打开操作,普通文件打开操作返回的是一个文件描述符,而socket()函数返回的是socket描述符,它唯一标识一个socket

参数:

参数名 描述
domain 协议域,又称协议族。

常用地协议族有:AF_INETAF_INET6AF_LOCAL (或称 AF UNIX, Unix 域 socket ) 、 AF_ROUTE 等 。

协议族决定了 socket的地址类型,在通信中必须采用对应的地址,如 AF_INET 决定了要用 ipv4 地址 ( 32 位) 与端口号( 16 位)的组合 、 AF_ROUTE 决定了要用一个绝对路径名作为地址 。
type 指定socket类型。

常用的socket类型:SOCK_STREAMSOCK_DGRAMSOCK_RAWSOCK_PACKETSOCK_SEQPACKET 等 。

SOCK_STREAM: 面向连接的可靠传输,即TCP协议。
SOCK_DGRAM: 面向无连接的不连续不可靠的传输,即UDP协议。
SOCK_RAW : 原始socket,可以读写ICMP及ICMP6、特殊的IP数据包(如自定义包)。
SOCK_PACKET: 与网络驱动程序直接通信,内核将不对网络数据进行处理而直接交给用户。
SOCK_STREAM: 提供连续可靠的数据包连接。
protocol 协议

常用协议:IPPROTO_TCP(TCP协议) , IPPTOTO_UDP(UDP协议) , IPPROTO_SCTP(SCTP协议)IPPROTO_TIPC(TIPC协议)

当protocol为0时,自动为type选择对应的协议

socket()函数调用成功,则返回一个新创建的套接字描述符,调用失败,则返回INVALID_SOCKET(linux中为-1)。套接字描述符是一个整型值,每个进程的进程空间里都有一个套接字描述符表,存放着套接字描述符和套接字数据结构的对应关系。

(2)bind函数

函数原型: int bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen) ;

通常服务器在启动的时候都会绑定一个众所周知的地址(如 ip 地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,有系统自动分配一个端口号和自身的 IP 地址组合 。bind函数就是把一个地址族中的特定地址赋值给socket(包含IP地址和端口号)。

返回值:如果函数执行成功,返回0,否则,返回SOCKET_ERROR

参数:

参数名 描述
sockfd 即socket描述符。
addr 一个 const struct sockaddr*指针,指向要绑定给 sockfd 的协议地址 。

该协议地址结构根据根据创建socket时使用的地址协议族的不同而不同,不同地址协议族的协议地址结构将会在表格下面列出。
addrlen 地址的长度

不同地址协议族的地址结构:
IPv4地址结构代码

struct sockaddr_in {
   
	sa_family_t     sin_family;		// 协议族为:AF_INET
	in_port_t       sin_port;		// 按网络字节顺序的端口号
	struct in_addr  sin_addr;		// 互联网地址
};
// 互联网地址
struct in_addr {
   
	uint32_t   s_addr;		// 网络字节顺序的地址
};

IPv6地址结构代码

struct sockaddr_in6 {
   
	sa_family_t     sin6_family;		// 协议族为:AF_INET6
	in_port_t       sin6_port;			// 按网络字节顺序的端口号
	uint32_t		sin6_flowinfo;		// IPv6流信息
	struct in6_addr sin6_addr;			// 互联网地址
	uint32_t		sin6_scope_id;		// 范围ID
};
// IPv6地址
struct in6_addr {
   
	unsigned char   s6_addr[16];</
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值