转行程序员浅谈进程间的socket通信

我在之前的文章中曾说过,我现在开始负责车辆以太网应用层协议栈的开发和维护。

以太网通信说白了也属于计算机通信的范畴,因此网络通信的5层模型仍然适用于车辆通信领域。

既然设计到ECU间的网络通信,那么socket网络编程的知识一定是必不可少的。

今天这篇文章就总结我这周学习的socket网络编程的知识。

Socket编程常用的函数

首先,下图是client与server之间的通信流程图。
Socket通信流程

根据上面的socket通信流程图,socket编程常用的函数如下:

  • 客户端使用socket(), connect(), send(), recv(), close();

  • 服务端使用socket(), bind(), listen(), accept(), recv(), send(), close();

Socket通信的三次握手和四次挥手
Socket建立连接三次握手的流程
  • 第一次握手:client端先向server端发送连接请求

  • 第二次握手:server收到后,回复ACK给client

  • 第三次握手:client端收到ACK后,回复ACK给server

至此,client与server之间的网络连接建立,可以顺利进行数据传输。
三次握手建立连接

Socket断开连接四次挥手的流程
  • 第一次挥手:client向server发送断开连接请求

  • 第二次挥手:server收到client的请求,回复ACK给client (这次挥手表示server收到了client的请求,但是并不会立即断开连接,可能还有未发送的数据)

  • 第三次挥手:server向client发送断开连接请求(这次挥手表示server端的数据已经发送完毕,client端可以断开)

  • 第四次挥手:client收到了server的请求,发送ACK给server。之后client端处于等待状态,过了一段时间后将socket关闭

至此,client与server之间的网络连接断开。
四次挥手断开连接

简单实现进程间的Socket的通信

实现步骤如下:
(1)使用socket套接字,并选择TCP/IP协议,端口号为6000

(2)客户端发送“this is a test”到服务端

(3)服务端收到后打印字符串,并回复“test ok”到客户端

(4)通信结束,断开连接

客户端socket通信的实现步骤
  • socket()创建socket

  • 设置socket的属性

  • connect()向服务端发起连接

  • send()向服务端发送消息

  • recv()等待服务端的消息

  • close()关闭socket,回收资源

//client.c
#include<stdio.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<netinet/in.h>
#define PORT 6000
int main()
{
    int socketfd, error;
    struct sockaddr_in serv_addr;
    
    //创建socket
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    //设置socket的属性
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    //向服务端发起连接
    error = connect(socketfd, &serv_addr, sizeof(struct sockaddr));
    if(0 != error)
    {
        printf("connect server error.");
        return 0;
    }
    //向服务端发送消息
    char *buff = "this is a test";
    error = send(socketfd, buff, strlen(buff), 0);
    if(-1 == error)
    {
        printf("send message to server error.");
        return 0;
    }
    //等待接收服务端的消息
    char recv_buff[1024] = {0};
    error = recv(socketfd, recv_buff, 1024,0);
    if(-1 == error)
    {
	printf("receive error");
	return 0;
    }
    printf("Receive buff:%s\n", recv_buff);
    //关闭socket,回收资源
    close(socketfd);
    return 0;
}
服务端socket通信的实现步骤
  • socket()创建socket
  • bind()对socket进行绑定
  • listen()监听绑定的socket,用于监听来自客户端的消息
  • accept()用于接收客户端的连接请求和消息
  • recv()函数接收客户端的消息,并将其保存到设置好的buffer中
  • send()函数用于服务端向客户端发送消息
  • close()关闭socket,回收资源
//server.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define PORT 6000
int main()
{
    int socketfd, clientfd, error;
    struct sockaddr_in server_addr, client_addr;
    int sin_size;
    char buff[1024] = {0};
    //创建socket
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == socketfd)
    {
        printf("create socket fail.");
        return 0;
    }
    //socket属性设置
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    //绑定socket
    error = bind(socketfd, &server_addr, sizeof(struct sockaddr_in));
    if(0 != error)
    {
        printf("bind fail.");
        close(socketfd);
        return 0;
    }
    //监听socket
    error = listen(socketfd, 5);
    if(0 != error)
    {
        printf("listen fail.");
        close(socketfd);
        return 0;
    }
    //接收客户端的连接请求
    clientfd = accept(socketfd, (struct sockaddr*)&client_addr, &sin_size);
    //连接建立后,接收客户端的消息
    error = recv(clientfd, buff, 1024,0);
    if(-1 == error)
    {
        printf("receive error");
        close(socketfd);
        return 0;
    }
    printf("Receive buff:%s\n", buff);
    //收到消息后,向客户端发送响应
    char *send_buff = "test ok.";
    error = send(clientfd, send_buff, strlen(send_buff), 0);
    if(-1 == error)
    {
        printf("send error");
        close(socketfd);
        return 0;
    }
    //关闭socket,回收资源
    close(socketfd);
    
    return 0;
}

代码完成后,使用gcc编译代码,生成server和client的可执行文件。

然后,在linux界面打开两个命令行,先运行server进程,再运行client进程,即可观察到两个进程之间的通信。

总结

这篇文章承接的是之前《白话计算机网络》,但当时工作较忙一直没有更新。

此外,如果想继续学习socket通信和网络协议,推荐一个开源项目tinyhttp。该项目通过500行代码,利用多线程和socket通信简单实现了http协议,是很适合初学者学习的资源,强烈推荐!!!

我这两天正在阅读该项目的源码,等把项目源码吃透,会写一篇总结出来。

参考资料:

https://www.cnblogs.com/niwotaxuexiba/p/9700764.html

https://blog.csdn.net/chenlycly/article/details/51657179

ps: 欢迎关注我的公众号[酷酷的coder],分享转行菜鸟程序员成长过程汇总的烦恼和反思.

酷酷的Coder

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值