在windows环境下用C++完成一个hello/hi网络聊天程序

    经过网络程序设计课程的学习,我们了解了socket网络程序编程,接下来,就要学以致用,完成一个hello/hi的网络聊天程序。 

  • Socket介绍 

        Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部。

    Socket起源于Unix,而Unix/Linux 基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式 来操作。Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。

你想给另一台计算机发消息,你知道他的IP地址,他的机器上同时运行着qq、迅雷、word、浏览器等程序,你想给他的qq发消息,那想一下,你现在只能通过ip找到他的机器,但如果让这台机器知道把消息发给qq程序呢?答案就是通过port,一个机器上可以有0-65535个端口,你的程序想从网络上收发数据,就必须绑定一个端口,这样,远程发到这个端口上的数据,就全会转给这个程序啦。

 

 

 

扫描二维码关注公众号,回复: 8130140 查看本文章
  • Socket通信套路

    当通过socket建立起2台机器的连接后,本质上socket只干2件事,一是收数据,一是发数据,没数据时就等着。Socket 建立连接的过程跟我们现实中打电话比较像,打电话必须是打电话方和接电话方共同完成的事情,我们分别看看他们是怎么建立起通话的。

接电话方(Socket服务器端):

打电话方(Socket客户端):

 

 

  • Socket套接字函数

服务端套接字函数

    S.bind():绑定主机,端口号到套接字。

    S.listen():开始tcp监听。

    S.accept():等待客户端连接到来。

客户端套接字函数

    S.connect():主动初始化TCP服务连接。

  • 一个简单的hello/hi网络聊天程序

服务器端代码如下:

#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
#define MAX 999
using namespace std;
int main()
{
    char send_buf[MAX], recv_buf[MAX];
    SOCKET ser_listen, ser_accept;
    SOCKADDR_IN listen_ADDR, accept_ADDR;
    WSADATA wsa;
    //绑定socket库版本
    if (WSAStartup(MAKEWORD(2,2),&wsa)<0)
      {
        cout << "绑定socket库版本失败" << endl;
        exit(EXIT_FAILURE);
       }
    //初始化协议族
    listen_ADDR.sin_family = AF_INET;
    listen_ADDR.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    listen_ADDR.sin_port = htons(5214);
    ser_listen = socket(AF_INET, SOCK_STREAM, 0);
    //绑定主机,端口
    if (bind(ser_listen, (SOCKADDR*)& listen_ADDR, sizeof(SOCKADDR))<0)
    {
        cout << "socket绑定失败!" << endl;
        WSACleanup();
        exit(EXIT_FAILURE);
    }
    //等待连接,此时ser_listen变为被动套接口
    if (listen(ser_listen, SOMAXCONN) < 0)
    {
        cout << "设置监听失败!" << endl;
        WSACleanup();
        exit(EXIT_FAILURE);
    }
    cout << "等待客户端连接!" << endl;
    //len必须提前初始化,不然accept错误
    int len = sizeof(SOCKADDR);
    //此时ser_accept为主动套接口
    if ((ser_accept = accept(ser_listen, (SOCKADDR*)& accept_ADDR, &len))<0)
    {
        cout << "连接失败!" << endl;
        WSACleanup();
        exit(EXIT_FAILURE);
    }
    cout << "连接建立,请在客户端输入!" << endl;
    //消息的传递
    while (1)
    {
        recv(ser_accept, recv_buf, MAX, 0);
        cout << "收到:" << recv_buf << endl << "请输入要发送的信息:" << endl;
        cin >> send_buf;
        send(ser_accept, send_buf, MAX, 0);
    }
    //结束关闭套接口
    closesocket(ser_listen);
    closesocket(ser_accept);
    WSACleanup();
}

客户端代码:

#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
#define MAX 999
using namespace std;
int main()
{
    char send_buf[MAX], recv_buf[MAX];
    SOCKET cli_accept;
    SOCKADDR_IN cli_ADDR;
    WSADATA wsa;
    //绑定套接字库版本
    if (WSAStartup(MAKEWORD(2, 2), &wsa) < 0)
    {
        cout << "绑定socket库版本失败" << endl;
        exit(EXIT_FAILURE);
    }
    //初始化协议族
    cli_ADDR.sin_family = AF_INET;
    cli_ADDR.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    cli_ADDR.sin_port = htons(5214);
    cli_accept = socket(AF_INET, SOCK_STREAM, 0);
    //连接到服务端套接口
    if (connect(cli_accept, (SOCKADDR*)& cli_ADDR, sizeof(SOCKADDR)) < 0) 
    {
        cout << "服务端连接失败!" << endl;
        WSACleanup();
        exit(EXIT_FAILURE);
    }
    else
    {
        cout << "服务端连接成功!" << endl;
    }
    //消息传递
    while (1)
    {
        cout << "请输入发送信息:" << endl;
        cin >> send_buf;
        send(cli_accept, send_buf, MAX, 0);
        recv(cli_accept, recv_buf, MAX, 0);
        cout << "收到:" << recv_buf << endl;
    }
    //关闭套接口
    closesocket(cli_accept);
    WSACleanup();
}

先运行server.exe,再运行client.exe,得到如下运行结果:

 

  

 

猜你喜欢

转载自www.cnblogs.com/rings/p/12014187.html