菜鸟成长记录【2】:网络编程 tcp_socket通信

SOCKET:

在计算机通信领域,socket 被翻译为“套接字”即(端口+地址),它是计算机之间进行通信的一种约定或一种方式。通过 socket这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据
socket起源于unix,而unix下“一切皆文件”,都可以用“打开open –> 读写write/read关闭close”模式来操作。

TCP:

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP_socket通信流程:

服务端:

  1. 创建socket
  2. 绑定主机的端口号及IP地址
  3. 监听是否有客户端请求接入
  4. 接受连接请求
  5. 数据传输通信
  6. 关闭socket

客户端:

  1. 创建socket
  2. 设置对方的ip地址及端口号
  3. 发起连接请求
  4. 数据传输通信
  5. 关闭socket

以下是我理解的通信流程:

就像两个人间的线上交流,前提是双方都先要注册自己的账号(创建socket),而建立交流时总会有被动或主动的一方;

被动方就像时服务器:你可以说他内向又渴望交流,注册号账号后就把自己的账号和自己公开信息结合了(绑定),在没有事做时他就在那等别人加他好友(监听),他看到后同意就建立了连接(接收连接请求),最后聊完了就下线(关闭socket);

主动方就像客户端:想要和被动那方说什么时,就需要查找搜索对方的账号(设置对方IP和端口),点击添加好友(发起连接请求)这一步当然不一定100%通过,也许就会出现什么特殊情况,对方同意后就可以正常交流,聊完下线(关闭socket)。

流程实现:

1.服务端查看自己的ip地址

在命令行输入ifconfig

 这个inet就是服务端需要绑定的ip。

2.需要用到的相关函数

创建socket

int socket(int domain, int type, int protocol);

发起连接

 int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

绑定

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

 监听

int listen(int sockfd, int backlog);

接受连接

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

发送/接受数据(因为Linux下一切皆文件,使用write/read也可以)

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

3.服务端的建立

int tcp_socket(const char *ip, int port)
{
        //创建socket
        int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
        if(-1 == socket_fd)
        {
                perror("create socket error");
                return -1;
        }
        printf("socket创建成功\n");

        //设置主机端口及ip地址
        struct sockaddr_in server;
        memset(&server,'\0',sizeof(server));

        server.sin_family = AF_INET;
        server.sin_port = htons(port);
        server.sin_addr.s_addr = inet_addr(ip);

        //绑定ip地址及端口
        if(bind(socket_fd,(struct sockaddr *)&server,sizeof(server)) < 0)
        {
                perror("bind error");
                return -1;
        }
        printf("bind ok\n");

        //监听是否有人连接 最大连接数5
        if(listen(socket_fd,5) < 0)
        {
                perror("listen error");
                return -1;
        }
        printf("listen ok\n");

        return socket_fd;
}

4.客户端的建立

int tcp_socket(const char *ip, int port)
{
        //创建socket ipv4 流式套接字(tcp)
        int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
        if(-1 == socket_fd)
        {
                perror("create socket error");
                return -1;
        }
        printf("socket创建成功\n");

        //指定服务端的端口及ip地址
        struct sockaddr_in server;
        memset(&server,'\0',sizeof(server));

        server.sin_family = AF_INET;              //使用的通信协议
        server.sin_port = htons(port);            //端口号
        server.sin_addr.s_addr = inet_addr(ip);   //ip地址

        //向指定ip端口的服务器发起连接请求
        if(connect(socket_fd, (struct sockaddr *)&server, sizeof(server)) < 0)
        {
                perror("connect error");
                return -1;
        }
        printf("发起连接请求\n");

        return socket_fd;
}

 5.数据通信

服务端

int main()
{
        int socket_fd = tcp_socket("192.168.139.138",6666);
        if(socket_fd < 0)
        {
                return -1;
        }

        //接受连接
        struct sockaddr_in client;
        int len = sizeof(client);
        int new_fd = accept(socket_fd,(struct sockaddr *)&client,&len);
        if(new_fd < 0)
        {
                perror("accept error");
                return -1;
        }
        printf("accept ok\n");
        printf("ip = %s\tport = %d\n",inet_ntoa(client.sin_addr),client.sin_port);

        //数据传输
        char buf[20] = {'\0'};
        recv(new_fd,buf,sizeof(buf),0);
        printf("接收到的数据为:%s",buf);

        return 0;
}

客户端

int main()
{
        //通信的建立
        int socket_fd = tcp_socket("192.168.139.138",6666);
        if(socket_fd < 0)
        {
                return -1;
        }

        //数据发送/接受
        char buf[20] = {'\0'};
        printf("请输入要发送的数据:");
        fgets(buf,sizeof(buf),stdin);
        send(socket_fd,buf,sizeof(buf),0);

        //关闭socket
        close(socket_fd);
}

 运行结果

 

我这是自己和自己玩,若要和别人的主机通信仅需修改封装好的tcp_socket()的参数即可。

以上若有错误,请大佬指出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值