博客主页:https://blog.csdn.net/wkd_007
博客内容:嵌入式开发、Linux、C语言、C++、数据结构、音视频
本文内容:介绍网络编程入门知识:TCP协议、TCP客户端、TCP服务端
金句分享:你不能选择最好的,但最好的会来选择你——泰戈尔
本文未经允许,不得转发!!!
TCP协议的全称是传输控制协议
(Transmission Control Protocol)。TCP是一个面向连接的协议,为用户进程提供可靠的全双工字节流。TCP套接字是一种流套接字( streamsocket)。TCP关心确认、超时和重传之类的细节。大多数因特网应用程序使用TCP。注意,TCP既可以使用IPv4,也可以使用IPv6。
TCP协议的几个特点:
编写TCP客户端的步骤:
- 1、创建TCP套接字
socket
;- 2、指定TCP服务端ip和端口,bzero、inet_pton
- 3、建立与TCP服务端的连接,
connect
- 4、交互数据
- 5、关闭套接字
#include
#include
#include
#include
#include
int main()
{
// 1、创建TCP套接字socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0)
perror("socket error" );
// 2、准备服务端ip和端口
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons (10086);
if (inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0) // 设置本机IP为服务端IP
perror("inet_pton error");
// 3、连接 connect
if (connect(sockfd,(struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
perror("connect error" );
// 4、交换数据
printf("TcpCli sockfd=%d, send msg\n",sockfd);
write(sockfd, "Hello,I am tcp client", strlen("Hello,I am tcp client"));
char recvline[256];
int n = 0;
while ( (n = read (sockfd, recvline, sizeof(recvline))) > 0)
{
recvline[n] = 0 ;/*null terminate */
printf("recv[%s]\n",recvline);
}
if (n < 0)
perror("read error" );
// 5、关闭
close(sockfd);
return 0;
}
socket 函数
#include /* See NOTES */
#include
int socket(int domain, int type, int protocol);
socket函数创建一个套接字描述符。man手册描述,socket创建一个通信端点并返回一个描述符。
domain
指定通信域,使用了AF_INET
,表示是IPv4 Internet protocols
协议的。type
指定套接字类型,使用``,表示TCP协议的套接字(提供有序、可靠、双向、基于连接的字节流。可以支持带外数据传输机制)。protocol
指定了要与套接字一起使用的特定协议。通常,在给定的协议族中,只有一个协议支持特定的套接字类型,在这种情况下,协议可以指定为0。connect 函数
#include /* See NOTES */
#include
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
connect 函数将文件描述符sockfd
引用的套接字连接到addr
指定的地址。addrlen
参数指定addr的大小。addr中地址的格式由套接字sockfd的地址空间决定;
编写TCP服务端的步骤:
- 1、创建TCP套接字
socket
;- 2、准备服务端ip和端口;
- 3、绑定,
bind
- 4、监听,
listen
- 5、接受客户端连接,
accept
- 6、与客户端进行数据交互
- 7、关闭套接字
#include
#include
#include
#include
#include
int main()
{
// 1、创建TCP套接字socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0)
perror("socket error" );
// 2、准备服务端ip和端口
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons (10086);
servaddr.sin_addr.s_addr = INADDR_ANY; // 指定ip地址为 INADDR_ANY,这样要是服务器主机有多个网络接口,服务器进程就可以在任一网络接口上接受客户端的连接
// 3、绑定 bind
if (bind(sockfd,(struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
perror("bind error" );
// 4、监听 listen
if(listen(sockfd, 10) != 0)
perror("listen error");
printf("TcpSer sockfd=%d, start listening\n",sockfd);
char recvline[256];
while(1)
{
// 5、接受客户端连接
int connfd = accept(sockfd, NULL, NULL);
// 6、与客户端交换数据
int n = read(connfd, recvline, sizeof(recvline));
if(n>0)
{
recvline[n] = 0 ;/*null terminate */
printf("recv connfd=%d [%s]\n",connfd,recvline);
}
write(connfd, "Hello,I am tcp server", strlen("Hello,I am tcp server"));
close(connfd);
}
// 7、关闭
close(sockfd);
return 0;
}
socket
、bind
和listen
这3个调用步骤是任何TCP服务器准备所谓的监听描述符(listening descriptor)的正常步骤。
tcp服务端相关函数有:socket、bind、listen、accept。socket函数可以参照上面 2.2 小节。
#include /* See NOTES */
#include
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
bind函数将addr指定的地址分配给文件描述符sockfd引用的套接字。addrlen指定addr指向的地址结构的大小。#include /* See NOTES */
#include
int listen(int sockfd, int backlog);
listen函数将sockfd引用的套接字标记为被动套接字
,标记后,可以使用accept
函数接受传入连接请求的套接字。
#include /* See NOTES */
#include
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept函数用于基于连接的套接字类型(SOCK_STREAM、SOCK_SEQPACKET)。它提取侦听套接字的挂起连接队列中的第一个连接请求sockfd,创建一个新的连接套接字,并返回一个引用该套接字的新文件描述符。新创建的套接字未处于侦听状态。原始套接字sockfd不受此调用的影响。本文主要介绍Linux下网络编程的基础知识,先是简单介绍一下TCP协议,然后给出一个TCP客户端、TCP服务端最简单的例子,最后介绍创建TCP客户端、TCP服务端需要用到的函数。
如果文章有帮助的话,点赞、收藏⭐,支持一波,谢谢