前言
本文将带大家学习什么是网络编程及如何去编写TCP和UDP程序。本文将基于百问网Linux应用开发视频和文档进行讲解。
一、网络编程简介
IP和端口
在网络传输中需要使用“IP和端口”来表示源或目的。
PC机上的ssh client和浏览器想访问同一个网站,ssh cilent想要使用ssh助手,浏览器想要使用http服务,他们都连接到同一个服务器IP就是相同的,那怎么样去区别这两个呢。
他们的端口号(port)是不相同的,一般来说http的端口号是80,而ssh的端口号是22。据此我们就可以将这两个不同的软件区分开了。
网络传输中的2个对象:server和client
我们经常访问网站,这涉及2个对象:网站服务器,浏览器。网站服务器平时安静地呆着,浏览器主动发起数据请求。网站服务器、浏览器可以抽象成2个软件的概念:server程序、client程序。
网络连接两种传输方式TCP和UDP
TCP和UDP原理上的区别
TCP向它的应用程序提供了面向连接的服务。这种服务有2个特点:可靠传输、流量控制(即发送方/接收方速率匹配)。它包括了应用层报文划分为短报文,并提供拥塞控制机制。
UDP协议向它的应用程序提供无连接服务。它没有可靠性,没有流量控制,也没有拥塞控制。
为什么存在UDP
既然TCP能可靠传输UDP是不可靠传输那为什么还需要UDP呢?
当使用视频通话时偶尔视频出现模糊是可以接受的,假如使用TCP连接需要保证数据的可靠性那么可能会导致后面数据的阻塞导致视频内容的滞后。而这个时候使用UDP就可以保证数据传输的效率。
TCP/UDP网络通信大概交互图
下图取自百问网开发手册
二、网络编程使用函数讲解
1.socket函数
使用socket这个函数需要包含下列头文件
此函数用于创建一个套件字
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>
int socket(int domain, int type, int protocol);
参数:domain:网络程序所在的主机采用的通讯协族
参数type:是网络程序所采用的通讯协议
SOCK_STREAM表明用的是TCP 协议,这样会提供按顺序的,可靠,双向,面向连接的比特流。
SOCK_DGRAM 表明用的是UDP协议,这样只会提不可靠,无连接的通信。
参数protocol:一般使用0代替。
2.bind函数
使用bind这个函数需要包含下列头文件
此函数用于绑定一个套接字
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd是由socket函数调用返回的文件描述符。
my_addr是一个指向sockaddr的指针。
addrlen是sockaddr结构的长度。
sockaddr的定义: struct sockaddr{ unisgned short as_family; char sa_data[14]; };
3.listen函数
使用listen这个函数需要包含下列头文件
此函数告诉服务器可以接受连接
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>
int listen(int sockfd, int backlog);
sockfd是bind后的文件描述符。
backlog设置请求排队的最大长度。当有多个客户端程序和服务端相连时,使用这个表示可以介绍的排队长度。
listen函数将bind的文件描述符变为监听套接字,返回的情况和bind一样。
4.accept函数
int accept(int sockfd, struct sockaddr *addr,int *addrlen);
服务器使用此函数获得连接请求,并且建立连接。
sockfd是listen后的文件描述符。
addr和addrlen分别传递指针即可。
函数成功接收返回返回最后的服务器端的文件描述符,接收失败返回-1。
5.connect函数
int connect(int sockfd, struct sockaddr * serv_addr,int addrlen);
使用此函数建立连接,
sockfd是socket函数返回的文件描述符。
serv_addr储存了服务器端的连接信息,其中sin_add是服务端的地址。
addrlen是serv_addr的长度
connect函数连接成功返回0,失败返回-1;
6.send函数
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
sockfd 指定发送端套接字描述符;
buf 指明一个存放应用程序要发送数据的缓冲区;
len 指明实际要发送的数据的字节数;
flags 一般置0。
返回值为ssize_t类型,函数发送成功返回发送字符串的大小,失败即返回-1;
7.recv函数
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
sockfd 指定接收端套接字描述符;
buf 指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
len 指明buf的长度;
flags 一般置0
和发送函数一样返回值都是ssize_t,函数接收成功返回发送字符串的大小,失败即返回-1;
8.sendto函数
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
dest_addr 表示目地机的IP地址和端口号信息,
addrlen 常常被赋值为sizeof (struct sockaddr)。
sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
总结
本文主要介绍了网络编程的一些概念和网络编程中会用到的函数下篇文章将带大家学习如何去写代码。