基于TCP的全双工网络编程实践

首先我们先了解一下什么是全双工通信?

全双工数据通信允许数据同时在两个方向上传输,因此,全双工通信相当于是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。

TCP服务端代码:

#include <stdio.h>             
#include <stdlib.h>           
#include <string.h>
#include <arpa/inet.h>             
#include <netdb.h>              
#include <netinet/in.h>       
#include <stdint.h>                       
#include <sys/socket.h>     
#include <sys/types.h>     
#include <unistd.h>      

#define PORT 10000  

void error()
{
    perror("Socket Creation Failed");
    exit(EXIT_FAILURE);
}

int main()
{
    uint32_t sockfd,conn; 
    char recvbuff[1024],sendbuff[1024]; 

    struct sockaddr_in server_addr,client_addr;  
    socklen_t ClientLen; 

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        error();  
    }

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    printf("Server is running...\n");

    int on=1;
    if((setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)))<0)
    {
        perror("setsockopt failed");
        exit(EXIT_FAILURE);
    }

    if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        error(); 
    }

    listen(sockfd, 5);

    printf("Server is listening...\n");

    conn = accept(sockfd, (struct sockaddr *)NULL, NULL);

    printf("Server is connected...\n");

    pid_t pid;
    pid = fork();
    if (pid == 0)  //子进程负责接收数据
    {
        while (1)
        {
            bzero(&recvbuff, sizeof(recvbuff));
            recv(conn, recvbuff, sizeof(recvbuff), 0);
            printf("\nCLIENT : %s\n", recvbuff);
            sleep(5);
        }
    }
    else  //父进程负责发送发送数据
    {
        while (1)
        {
            bzero(&sendbuff, sizeof(sendbuff));
            printf("\nType message here: ");
            fgets(sendbuff, 1024, stdin);
            send(conn, sendbuff, strlen(sendbuff) + 1, 0);
            printf("\nMessage Sent!\n");
            sleep(5);
        }
    }

    close(sockfd);
    printf("Server is offline...\n");
    return 0;
}

TCP服务端运行状态:

TCP客户端代码:

#include <stdio.h>             
#include <stdlib.h>          
#include <string.h> 
#include <arpa/inet.h>             
#include <netdb.h>               
#include <netinet/in.h>          
#include <stdint.h>                   
#include <sys/socket.h>     
#include <sys/types.h>     
#include <unistd.h>   

#define PORT 10000  

void error()
{
    perror("Socket Creation Failed");
    exit(EXIT_FAILURE);
}

int main()
{
    uint32_t sockfd; 
    char sendbuff[1024],recvbuff[1024]; 

    struct sockaddr_in server_addr; 

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        error();
    }

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    printf("Client is running...\n");

    connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));

    printf("Client is connected...\n");

    pid_t pid;
    pid = fork();
    if (pid == 0)  //子进程
    {
        while (1)
        {
            bzero(&sendbuff, sizeof(sendbuff));
            printf("\nType message here: ");
            fgets(sendbuff, 1024, stdin);
            send(sockfd, sendbuff, strlen(sendbuff) + 1, 0);
            printf("\nMessage sent!\n");
            sleep(5);
        }
    }
    else  //父进程
    {
        while (1)
        {
            bzero(&recvbuff, sizeof(recvbuff));
            recv(sockfd, recvbuff, sizeof(recvbuff), 0);
            printf("\nSERVER: %s\n", recvbuff);
            sleep(5);
        }
    }

    close(sockfd);
    printf("Client is offline...\n");
    return 0;
}

TCP客户端运行状态:

有时候我们会遇到这样的问题,当你第二次第三次......运行程序的时候,报如下的问题:

Socket Creation Failed: Address already in use

解决方法:

    int on=1;
    if((setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)))<0)
    {
        perror("setsockopt failed");
        exit(EXIT_FAILURE);
    }

【欢迎关注编码小哥,学习更多实用的编程方法】

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编码小哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值