TCP控制传输协议例题

						TCP服务端
						socket()
						|
						v
  						bind()
						|
						v
						listen()
						|
						v
		TCP客户端		accept()
		socket()		|
			|			v
			v   建立连接 阻塞直到有客户端链接
		connect()<----->|
			|			v
+------>write()------->read()/recv()<---+
|			|  数据请求	|			    |
|			|			|			    |
|			v			V处理请求        | 
+-------read()<---------write()---------+
			|  回应数据	|
			v			v
		close()-------->read()
		    	结束链接	|
						v
						close()

TCP特点:

1,有链接,提供可靠服务

2,有应答

3,超时重传

4,拥塞控制

5,数据与数据之间没有边界,这但与UDP差异很大

6,存在黏包问题,发的数据包没有边界,接收方无法解析(解决方法:1.固定大小,结构体 2.添加结束标志:譬如\0,可以双方约定)

7,TCP是一个面向连接的传输层协议。通讯过程中链路一直保持。

8,TCP是全双工通信模式,因为收发两端都设有缓存区

9,TCP面向字节流。

TCP小栗子:

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

服务端:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <time.h>

typedef struct sockaddr* (SA);
int main()
{
    int lisfd = socket(AF_INET,SOCK_STREAM,0);
    if(lisfd == -1)
    {
        perror("socket fail");
        return -1;
    }

    struct sockaddr_in ser,cli;
    bzero(&cli,sizeof(cli));
    bzero(&ser,sizeof(ser));
    ser.sin_family = AF_INET;
    ser.sin_addr.s_addr = INADDR_ANY;
    ser.sin_port = htons(60000);
    int ret_bind = bind(lisfd,(SA)&ser,sizeof(ser));
    if(ret_bind == -1)
    {
        perror("bind fail");
        return -1;
    }
    listen(lisfd,3);
    socklen_t len = sizeof(cli);
    //通信套接字:
    int conn = accept(lisfd,(SA)&cli,&len);
    if(conn == -1)
    {
        perror("accept fail");
        return -1;
    }

    //int i = 0;
    while(1)
    {
        char buf[1024] = {0};
        bzero(&buf,sizeof(buf));
        size_t ret = recv(conn,buf,sizeof(buf),0);
        if(ret<=0)
        {
            break;
        }
        //sprintf(buf,"%s %s",buf,tm);
        timer_t tm;
        time(&tm);
        sprintf(buf,"%s->%s",buf,ctime(&tm));
        //i++;
        send(conn,buf,sizeof(buf),0);
    }

    close(lisfd);
    close(conn);

    return 0;
}

客服端:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
typedef struct sockaddr * (SA);
int main()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
    {
        perror("socket fail");
        return -1;
    }
    struct sockaddr_in ser,cli;
    bzero(&cli,sizeof(cli));
    bzero(&ser,sizeof(ser));
    ser.sin_addr.s_addr = INADDR_ANY;
    ser.sin_family = AF_INET;
    ser.sin_port = htons(60000);
    int ret = connect(sockfd,(SA)&ser,sizeof(ser));
    if(ret == -1)
    {
        perror("connect fail");
        return -1;
    }

    int i = 10;
    while(i--)
    {
        char buf[1024] = "hello! ";
        send(sockfd,buf,sizeof(buf),0);
        recv(sockfd,buf,sizeof(buf),0);
        printf("%s\n",buf);

        fflush(stdout);
        sleep(1);
    }

    close(sockfd);
    // printf();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值