TCP流程及代码

本文详细介绍了TCP通信中,服务器端如何通过socket创建、绑定、监听并接受客户端连接,以及客户端如何发起连接、发送和接收数据的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP流程

 实现-不借助第三方软件实现主机之间的通信。 socket

 打个比方,TCP通信的服务端就像一个害羞的女孩子客户端像一个追求的男孩子

 一开始,服务端:1.女孩子买了一个手机(socket);

                              2.给手机添加自己的消息电话号码(struct sockaddr_in 填充IP端口等)

                              3.绑定手机卡(bind);

                              4.不给别人打电话,被动监听男孩的来电(listen主动变被动);

                              5.等待来电,不干其他的(accept);

                              6.如果接收到男孩(客户端)的来电,就听听男孩说了什么(recv)或者  自己说点什么(send);

                              7.最后挂掉电话(close).

               客户端:1.男孩买了一个手机(socket);

                              2.给手机添加女孩的消息电话号码(struct sockaddr_in 填充IP端口等)

                              3.给女孩打电话,发起请求,不干其他的(connect);

                              6.如果电话打通了,就对女孩说话(send)或者 听听女孩说的(recv);

                              7.最后挂掉电话(close).

服务器端:

1) socket(),创建套接字文件,创建出用于连接的套接字文件
2) bind() ,绑定,把socket()函数返回的文件描述符和IP、端口号进行绑定,
3) listen() ,监听将socket(返回的文件描述符,由主动套接字变为被动套接字,
4) accept() ,阻塞函数,阻塞等待客户端的连接请求,返回一个用于通信的套接字文件,
5) recv(),接收客户端发来的数据;(read)
//6) send(),发送数据;(write)
7) close(), 关闭文件描述符,少要关闭连接、通信

客户端:

1)socket(),创建套接字文件, 既用于连接,也用于通信;
     填充结构体填充服务器的ip和端口,用于connect连接
2) connect(),用于发起连接请求,阻塞等待连接服务器,
3) send(),发送数据;
//4) recv(),接收数据;
5) close(), 关闭文件描述符;

 TCP代码

服务端

#include <stdio.h>
#include <stdlib.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 <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char const *argv[])
{
    //1.创建套接字   返回一个建立连接的文件描述符
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("socket is err:");
        return -1;
    }

    //2.填充结构体
    struct sockaddr_in saddr,caddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[2]));
    saddr.sin_addr.s_addr = inet_addr("0.0.0.0");

    int len = sizeof(caddr);

    if(bind(sockfd,(struct sockaddr *)&saddr,sizeof(saddr))<0)
    {
        perror("bind is err:");
        return -1;
    }

    //3.监听
    if(listen(sockfd,5) < 0)
    {
        perror("listen is err:");
        return -1;
    }

    //4. 阻塞等待客户端的链接
    while(1)
    {
        int acceptfd = accept(sockfd,(struct sockaddr *)&caddr,&len);
        if(acceptfd < 0)
        {
            perror("accept is err:");
            return -1;
        }
        
        char buf[128] = "";
        int recvbyte;
        while(1)
        {
                recvbyte = recv(acceptfd,buf,sizeof(buf),0);
                if(recvbyte < 0)
                {
                    perror("recv is err:");
                    return -1;
                }
                else if(recvbyte == 0)
                {
                    printf("client is exit\n");
                    break;
                }
                else
                {
                    printf("%s\n",buf);
                }
        }
    close(acceptfd);
    }

    close(sockfd);
    return 0;
}

客户端

#include <stdio.h>
#include <stdlib.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 <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    if(argc != 3)
    {
        printf("please input %s <ip> <port>\n",argv[0]);
    }
    //1.创建套接字
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("socket is err:");
        return -1;
    }
   //2. 填充结构体
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[2]));
    saddr.sin_addr.s_addr = inet_addr(argv[1]);
   // 链接
    if(connect(sockfd,(struct sockaddr *)&saddr,sizeof(saddr)) < 0)
    {
        perror("connect is err:");
        return -1;
    }
   
   char buf[128] = "";
   while(1)
   {
       fgets(buf,sizeof(buf),stdin);
         if(buf[strlen(buf)-1] == '\n')
           buf[strlen(buf) -1] = '\0';
        
       send(sockfd,buf,sizeof(buf),0);
   }

   close(sockfd);
    return 0;
}

  大家还有什么不懂的地方可以讨论讨论哦~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值