网络编程

来源:互联网 发布:中国警察智识数据库 编辑:程序博客网 时间:2024/06/02 14:40
网络通信:全双工

TCP和UDP
相同点:同属传输层
区别:
TCP:有连接:通信双方在通信之前事先建立连接,类似于打电话。
整个通信过程可以保证可靠的传输,即数据不会丢包、失序、乱码等,TCP在传输过程中还可实现流量控制。
使用场合:可靠新要求比较高的场合,比如账户密码、文件传输等。
UDP:无连接,类似于寄信。
整个通信过程中数据包可能会出现丢包和失序等,也没有流量控制。
适用场合:视频通信、及时聊天等。

流式套接字(SOCK_STREAM):基于TCP协议通信的套接字
提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。

数据报套接字(SOCK_DGRAM):基于UDP协议的套接字
提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。

原始套接字(SOCK_RAW):不经过传输层,故无默认的tcp层协议。
可以对较低层次协议如IP、ICMP直接访问。

端口号:为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区别
1——1023已经固定的用于某些通信服务,用户不能复用。

编程API:

一、TCP服务器端通信模型:
1.创建套接字
int socket (int domain, int type, int protocol);
功能:创建通信套接字
参数:
domain:指明通信套接字的使用地方
type:指明通信套接字类型(SOCK_STREAM, SOCK_DGRAM, SOCK_RAW)
protocol:指明使用的特殊协议
返回值:
成功:新创建的套接字文件描述符
失败:-1

2.为本地套接字绑定地址信息
int bind(int sockfd, struct sockaddr *my_addr, int addrlen); 
功能:为本地套接字绑定地址信息
参数:
sockfd:指明需要绑定的本地套接字
my_addr:指向含有地址信息的结构体空间
addrlen:表明绑定的地址信息长度
返回值:
成功:0
失败:-1

internet通信地址信息:
struct sockaddr_in {
        sa_family_t    sin_family; /* address family: AF_INET */
        in_port_t      sin_port;   /* port in network byte order */——>需要进行字节序转换
        struct in_addr sin_addr;   /* internet address */
    };


    /* Internet address. */
        struct in_addr {
        uint32_t       s_addr;     /* address in network byte order */——>需要进行字节序转换
    };

字节序转换:
主机字节序转网络字节序:
u_long htonl (u_long hostlong);
u_short htons (u_short short);

网络字节序到主机字节序
u_long ntohl (u_long hostlong);
u_short ntohs (u_short short);

IP地址转换:
inet_aton()
将strptr所指的字符串转换成32位的网络字节序二进制值
#include <arpa/inet.h>
int inet_aton(const char *strptr,struct in_addr *addrptr);

inet_addr()
功能同上,返回转换后的地址。
in_addr_t inet_addr(const char *strptr);

inet_ntoa()
将32位网络字节序二进制地址转换成点分十进制的字符串。 
char *inet_ntoa(stuct in_addr inaddr);

建立连接:
3.监听
int listen (int sockfd, int backlog);
功能:为套接字sockfd创建监听队列,用于服务器端。
参数:
sockfd:本地套接字
backlog:监听队列大小
返回值:
成功:0
失败:-1

4.接收客户端连接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:接受客户端的连接请求
参数:
sockfd:本地套接字
addr:指向存储客户端地址信息的结构体空间
addrlen:(值结果参数)指明客户端地址信息存储长度
返回值:
成功:返回已经建立连接的套接字文件描述符
失败:-1

收发消息:
5.收发消息
ssize_t  send(int  socket,  const  void  *buffer,  size_t  length, int flags);
功能:发送消息
参数:
socket:本地套接字
buffer:要发送的消息的首地址
length:指明消息长度
flags:发送消息的标志位,默认0
返回值:
成功:成功发送到内核发送缓冲区的字节数,不能用于表示对方成功接收的字节数。(tcp内部存在一个发送缓冲区)
失败:-1

ssize_t  recv(int  socket,  void  *buffer,  size_t  length, int flags);
功能:从本地套接字接收消息
参数:
socket:本地套接字
buffer:指明收到的消息的存储首地址。
length:指明接收消息长度
flags:指明接收方式
返回值:
成功:返回成功从内核接收缓冲区拷贝到buffer的字节数,返回0表示对方发送端关闭。
失败:返回-1

6.关闭不用的套接字
int close(int sockfd);

二、TCP客户端通信模型
1.创建套接字
2.绑定本地地址信息(可选)
3.向服务器发起连接请求
int?connect(int?sockfd,?struct?sockaddr?*serv_addr, int?addrlen);
功能:向对方发起连接请求
参数:
sockfd:指明本地套接字
serv_addr:指明对方的地址信息
addrlen:指明地址信息的长度
返回值:
成功:0
失败:-1
4.收发消息
5.关闭不用的套接字

思考题:
什么是粘包,为什么会出现粘包,UDP有粘包吗?
粘包怎么解决?
0 0
原创粉丝点击