网络编程---TCP

**1.TCP:**传输控制协议,位于传输层

2.TCP的特性:

a.使用流式套接字,数据连续,有顺序

b.TCP是可靠传输,有有应答机制 ACK,即收到数据后会明确告知发送方已收到数据;若发送方没有在预计时间收到应答,则会自动重传刚刚的数据

c.TCP在建立连接后传输链路会一直存在

d.TCP为全双工通信,在同一时刻既可以收也可以发

e.为满足同时收发,TCP存在双缓冲区,每个大小为64k,当缓冲区满时,会发生相应阻塞

3.TCP的收发过程:

三次握手过程

1.客户端向服务端发送SYN连接请求信号和随机初始序列号 (Client ISN)

2.服务端向客户端发送ACK 确认信号和SYN连接请求信号,并发送自己的随机初始序列号 (Server ISN)

3.客户端向服务端发送ACK确认信号

四次挥手过程

a.客户端向服务端发送FIN 结束连接请求信号,和SYN连接请求信号

b.服务端向客户端发送ACK确认信号

c.服务端向客户端发送FIN 结束连接请求信号和ACK确认信号

d.客户端向服务端发送ACK确认信号,连接结束

4.TCP函数的调用顺序

1)TCP服务端

a.socket()产生一个监听套接字

b.bind()绑定源地址

c.listen()监听

d.accept()建立连接,产生通信套接字,即三次握手过程

e.read(),write()

f.close()关闭监听套接字

2)TCP客户端

a.socket()产生一个套接字

b.accept()建立连接,产生通信套接字,即三次握手过程

c.read(),write()

d.close()关闭套接字

5.使用TCP从客户端向服务端发送一个照片文件

ser端

cpp 复制代码
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef struct sockaddr *(SA);
int	main(int argc, char **argv)
{
    int fd=open("2.jpg", O_WRONLY|O_CREAT|O_TRUNC,0666);
    int listfd=socket(AF_INET,SOCK_STREAM,0);
    if(-1==listfd)
    {
        perror("socket fail\n");
        return 1;
    }
    struct sockaddr_in ser,cil;
    bzero(&ser, sizeof(ser));
    bzero(&cil, sizeof(cil));
    socklen_t len=sizeof(cil);
    ser.sin_family=AF_INET;
    ser.sin_port=htons(50000);
    //127.0.0.1表示自己的ip地址,本机自己收发
    //ser.sin_addr.s_addr=inet_addr("127.0.0.1");
    ser.sin_addr.s_addr=INADDR_ANY;
    int ret=bind(listfd, (SA)&ser, sizeof(ser));
    if(-1==ret)
    {
        perror("blind");
        return 1;
    }
    listen(listfd, 3);//三次握手的排队数
    int conn=accept(listfd, (SA)&cil, &len);//conn为通信套接字
    if(conn==-1)
    {
        perror("accept");
        return 1;
    }

    while(1)
    {
        char buf[1024]={0};
        //int ret=recv(conn, buf, sizeof(buf), 0);
        int ret=recvfrom(conn, buf, sizeof(buf), 0,(SA)&cil,&len);
        if(ret<=0)//==0说明对方连接断开
        {
            break;
        }
        write(fd, buf, ret);
        bzero(buf, sizeof(buf));
        strcpy(buf,"ok");
        send(conn, buf, strlen(buf), 0);
    }
    close(listfd);
    close(conn);

    return 0;
}

cli端

cpp 复制代码
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <time.h>
#include <fcntl.h>
typedef struct sockaddr *(SA);
int	main(int argc, char **argv)
{
    int fd=open("1.jpg", O_RDONLY);
    if(-1==fd)
    {
        perror("open");
        return 1;
    }
    int conn=socket(AF_INET, SOCK_STREAM, 0);
    if(-1==conn)
    {
        perror("socket");
        return 1;
    }
    struct sockaddr_in ser;
    bzero(&ser,sizeof(ser));

    ser.sin_family=AF_INET;
    ser.sin_port=htons(50000);
    ser.sin_addr.s_addr=INADDR_ANY;

    int ret=connect(conn, (SA)&ser, sizeof(ser));
    if(-1==ret)
    {
        perror("connect error\n");
        return 1;
    }

    while (1)
    {
        char buf[1024]={0};
        int ret=read(fd, buf, sizeof(buf));
        if(ret<=0)
        {
            break;
        }
        send(conn, buf, ret, 0);
        bzero(buf, sizeof(buf));
        recv(conn, buf, sizeof(buf), 0);
    }
    close(conn);
    close(fd);
    return 0;
}

6.数据的粘包

发送方发送数据,接收方无法解析数据

解决方案:

a.设置边界

b.固定大小

c.自定义协议

相关推荐
牛奶咖啡136 小时前
基于Cobbler的系统自动化安装部署——Cobbler的安装部署实践
linux·运维·服务器·cobbler·cobbler的安装配置·cobbler环境检查问题解决·cobbler中导入系统镜像
mounter6256 小时前
深度解析 RDMA 技术的里程碑:基于 DMA-BUF 的 P2P 直接访问(GPU Direct RDMA 新姿势)
linux·运维·服务器·网络·p2p·kernel
taxunjishu7 小时前
MODBUS TCP转Profinet 化工安全管控物联网网关实战案例
网络·物联网·自动化
李白的天不白7 小时前
linux安装MongoDB
linux·运维·服务器
taxunjishu7 小时前
MODBUS TCP转Profinet 家纺织造塔讯物联网网关应用实操案例
物联网·网络协议·tcp/ip
乾元7 小时前
全球治理: 从《AI 法案》看安全合规的国际趋势
网络·人工智能·安全·机器学习·网络安全·架构·安全架构
-Excalibur-7 小时前
IP数据包在计算机网络传输的全过程
java·网络·c++·笔记·python·网络协议·智能路由器
BioRunYiXue7 小时前
从现象到机制:蛋白降解调控研究的系统策略与实验设计
java·linux·运维·服务器·网络·人工智能·eclipse
历程里程碑7 小时前
41 .UDP -3 群聊功能实现:线程池助力多客户端通信
linux·开发语言·网络·数据结构·c++·网络协议·udp
ALex_zry7 小时前
通用RPC跨平台方案设计
网络·网络协议·rpc