回射服务器

回射服务器练习

客户端任务:

  1. 能从键盘获取输入,发给服务器
  2. 能收到服务器的消息,并打印

服务器任务:

  • 接收客户端的消息,把消息原封不动的返回去

客户端伪代码:子进程read,父进程write

客户端代码:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
using namespace std;

#include <errno.h>

#define PUB_MSG_TYPE 256

#define ERR_EXIT(m) \
    do{\
        perror(m);\
        _exit(1); \
    } while (0)


int main()
{
    int ret = 0;
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);//创建socket
    if (socket_fd == 1)
        ERR_EXIT("socket");
    //绑定ip和端口
    struct  sockaddr_in ser_addr;
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_port = htons(8095);
    inet_aton("192.168.1.9", &ser_addr.sin_addr);

    ret = connect(socket_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr));
    if (ret == -1)
        ERR_EXIT("connect");
    cout << "connect success" << endl;

    pid_t  pid = fork();
    if (pid == 0)
    {
        //子进程进行读取数据
        char rbuf[1024] = { 0 };
        while (1)
        {
            ret = read(socket_fd, rbuf, sizeof(rbuf));
            if (ret == 0)
            {
                cout << "server is off" << endl;
                break;
            }
            cout << "read:" << rbuf << endl;
            memset(rbuf, 0x0, sizeof(rbuf));
        }
        exit(EXIT_SUCCESS);
    }

    //父进程负责从键盘获取数据输入  发送给服务器
    char sbuf[1024] = { 0 };
    while (fgets(sbuf, sizeof(sbuf), stdin) != 0)//stdin标准输入
    {
        write(socket_fd, sbuf, sizeof(sbuf));
        memset(sbuf, 0x0, sizeof(sbuf));
    }
    return 0;
}

服务器代码

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <string.h>
using namespace std;

#include <errno.h>

#define PUB_MSG_TYPE 256

#define ERR_EXIT(m) \
    do{\
        perror(m);\
        exit(1); \
    } while (0)
//服务器
int main()
{
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);//创建一个TCPsocket
    if (socket_fd == 1)
        ERR_EXIT("socket");
    //绑定ip和端口
    struct  sockaddr_in ser_add;
    ser_add.sin_family = AF_INET;
    ser_add.sin_port = htons(8095);//端口号
    ser_add.sin_addr.s_addr = htonl(INADDR_ANY);

    //地址可重复使用
    int on = 1;
    setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    int ret = bind(socket_fd, (struct sockaddr*)&ser_add, sizeof(ser_add));
    if (ret == -1)
        ERR_EXIT("bind");

    ret = listen(socket_fd, SOMAXCONN);//监听数据存放队列中
    if (ret == -1)
        ERR_EXIT("listen");

    struct sockaddr_in cli_add;
    socklen_t add_len = sizeof(cli_add);
    //int add_len = sizeof(cli_add);
    cout << "wait for client..." << endl;
  
       int  con_fd = accept(socket_fd, (struct sockaddr*)&cli_add, &add_len);
        cout << "someone on line..." << endl;
        char buf[1024] = { 0 };
        while (1)
        {
            read(con_fd, buf, sizeof(buf));
            cout << "buf=" << buf << endl;
            write(con_fd, buf, sizeof(buf));
            memset(buf, 0, sizeof(buf));
        }
    return 0;
}

客户端效果:

服务器效果

以上是只能连接单个服务器

对服务器进行升级可以进行多个服务器的连接

服务器代码:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <string.h>
using namespace std;

#include <errno.h>

#define PUB_MSG_TYPE 256

#define ERR_EXIT(m) \
    do{\
        perror(m);\
        exit(1); \
    } while (0)
//服务器
int main()
{
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);//创建一个TCPsocket
    if (socket_fd == 1)
        ERR_EXIT("socket");
    //绑定ip和端口
    struct  sockaddr_in ser_add;
    ser_add.sin_family = AF_INET;
    ser_add.sin_port = htons(8095);//端口号
    ser_add.sin_addr.s_addr = htonl(INADDR_ANY);

    //地址可重复使用
    int on = 1;
    setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    int ret = bind(socket_fd, (struct sockaddr*)&ser_add, sizeof(ser_add));
    if (ret == -1)
        ERR_EXIT("bind");

    ret = listen(socket_fd, SOMAXCONN);//监听数据存放队列中
    if (ret == -1)
        ERR_EXIT("listen");

    struct sockaddr_in cli_add;
    socklen_t add_len = sizeof(cli_add);
    //int add_len = sizeof(cli_add);
    cout << "wait for client..." << endl;
  
    while (1)
    {
        int  con_fd = accept(socket_fd, (struct sockaddr*)&cli_add, &add_len);
        cout << "someone on line..." << endl;

        pid_t pid = fork();
        if (pid == 0)
        {
            char buf[1024] = { 0 };
            while (1)
            {
                ret = read(con_fd, buf, sizeof(buf));
                if (ret == 0)
                {
                    cout << "client is offline" << endl;
                    break;
                }
                cout << "buf=" << buf << endl;
                write(con_fd, buf, sizeof(buf));
                memset(buf, 0, sizeof(buf));
            }
            exit(EXIT_SUCCESS);
        }
    }
      
       
    return 0;
}

效果图

服务器可以接收多个客户端

客户端1

客户端2

猜你喜欢

转载自blog.csdn.net/m0_49036370/article/details/113858536
今日推荐