C/C++ TCP winsock socket套接字/消息互传

C/C++ TCP winsock socket套接字/消息互传

—-server端代码

//server
#include <iostream>
#include <stdio.h>
#include <WinSock2.h>
#include <time.h>

using namespace std;

#pragma comment(lib, "ws2_32.lib")

#define buf 1460

void systime();

int main(int argc, char* argv[])
{
    WSADATA wsadata;
    int RWSU = WSAStartup(MAKEWORD(2, 2), &wsadata);
    if (RWSU != 0)
    {
        cout << "初始化失败" << endl;
        return 0;
    }

    //socket
    SOCKET s;
    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s == INVALID_SOCKET)
    {
        cout << "创建套接字失败" << WSAGetLastError() << endl;
        return -1;
    }


    //创建服务器端的地址结构
    struct sockaddr_in s_in;
    s_in.sin_family = AF_INET;
    s_in.sin_port = htons(5111);
    s_in.sin_addr.s_addr = htonl(INADDR_ANY);
    //sin.sin_zero[8] = 0;

    int bindResult = bind(s, (sockaddr*)&s_in, sizeof(sockaddr));

    if (bindResult != 0)
    {
        cout << "绑定套接字失败"<< WSAGetLastError()<< endl;
        return -1;
    }

    //listen()
    int listenResult = listen(s, 5);
    if (listenResult != 0)
    {
        cout << "listen error()" << WSAGetLastError() << endl;
        return -1;
    }

    SOCKET ss;
    sockaddr_in c_in;
    int addrlen = sizeof(sockaddr);
    ss = accept(s, (sockaddr*)&c_in, &addrlen);
    if (ss == INVALID_SOCKET)
    {
        cout << "accept套接字失败" << WSAGetLastError() << endl;
        return -1;
    }
    closesocket(s);
    while (true)
    {
        char recvf[buf];
        memset(recvf, 0, buf);
        int Rrecv = recv(ss, recvf, buf, 0);

        if (Rrecv == SOCKET_ERROR)
        {
            cout << "接收失败" << WSAGetLastError()<< endl;
            return -1;
        }

        SYSTEMTIME st;
        cout << "来自客户端的消息("; systime(); cout << endl;
        cout << recvf << endl;
        if (strcmp(recvf, "exit") == 0)
            break;

        cout << "请输入要发送的消息" << endl;
        char sendmessage[buf];
        memset(sendmessage, 0, sizeof(sendmessage));
        cin >> sendmessage;
        int sendResult = send(ss, sendmessage, sizeof(sendmessage), 0);
        if (sendResult == SOCKET_ERROR)
        {
            cout << "server 发送失败" << WSAGetLastError() << endl;
            return -1;
        }
        else 
            cout << "消息成功发送("; systime(); cout << endl;
        if (strcmp(sendmessage, "exit") == 0)
            break;
    }
    Sleep(1000);
    int RClo = closesocket(ss);
    if (RClo != 0)
    {
        cout << "close socket error" << WSAGetLastError() << endl;
        return 0;
    }

    //WSACleanup();
    int RWCU = WSACleanup();
    if (RWCU != 0)
    {
        cout << "注销失败" << WSAGetLastError() << endl;
        return 0;
    }
    return 0;
}

void systime()
{
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    cout << asctime(timeinfo);
}

—-cilent客户端代码

//cilent
#include <iostream>
#include <Winsock2.h>
#include <stdio.h>
#include <time.h>

using namespace std;

#pragma comment(lib, "ws2_32.lib")

#define buf 1460

void systime();

int main()
{
    char send_message[buf];
    memset(send_message, 0, buf);

    //初始化winsock
    WSADATA wsadata;
    WSAStartup(MAKEWORD(2, 2), &wsadata);
    int RWSU = WSAStartup(MAKEWORD(2, 2), &wsadata);
    if (RWSU != 0)
    {
        cout << "初始化失败" << endl;
        return 0;
    }

    //创建SOCKET
    SOCKET s;
    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s == INVALID_SOCKET)
    {
        cout << "创建套接字失败" << WSAGetLastError() << endl;
        return -1;
    }

    //IP地址,填写要链接的服务器的地址
    //const char FAR* cp = "127.0.0.1";
    struct sockaddr_in s_in;
    s_in.sin_family = AF_INET;
    s_in.sin_port = htons(5111);
    s_in.sin_addr.s_addr = inet_addr("127.0.0.1");

    //connect
    int connectResult = connect(s, (struct sockaddr*)&s_in, sizeof(sockaddr));
    if (connectResult != 0)
    {
        cout << "connect socket error" << WSAGetLastError() << endl;
        return -1;
    }

    while (TRUE)
    {
        cout << "请输入要发送的信息" << endl;
        cin >> send_message;

        int sendResult = send(s, send_message, sizeof(send_message), 0);
        if (sendResult == SOCKET_ERROR)
        {
            cout << "发送失败"<< WSAGetLastError() << endl;
            return -1;
        }
        cout << "信息成功发送("; systime(); cout << endl;
        if (strcmp(send_message, "exit") == 0)
            break;

        char recvmessage[buf];
        memset(recvmessage, 0, sizeof(recvmessage));
        int recvResult = recv(s, recvmessage, sizeof(recvmessage), 0);
        if (recvResult == SOCKET_ERROR)
        {
            cout << "信息接收失败" << WSAGetLastError() << endl;
            return -1;
        }
        else
        {
            cout << "来自服务器端的消息("; systime(); cout << endl;
            cout << recvmessage << endl;
        }
        if (strcmp(recvmessage, "exit") == 0)
            break;

    }
    Sleep(1000);

    //close
    int RClo = closesocket(s);
    if (RClo != 0)
    {
        cout << "close socket error" << WSAGetLastError() << endl;
        return -1;
    }
    //WSACleanup()
    int RWCU = WSACleanup();
    if (RWCU != 0)
    {
        cout << "注销失败" << WSAGetLastError() << endl;
        return -1;
    }
    return 0;
}

void systime()
{
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    cout << asctime(timeinfo);
}

运行截图
首先打开服务器端,再打开客户端

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
本文将介绍如何使用MFC Winsock实现基于TCP协议的C/S聊天程序。该程序包括一个服务器端和一个客户端,客户端可以与服务器端进行连接并发送消息,服务器端可以接收客户端发送的消息并将其广播给所有连接的客户端。 1. 创建MFC应用程序 首先,我们需要创建一个MFC应用程序。在Visual Studio中,选择“新建项目”,然后选择“MFC应用程序”。 在“应用程序类型”选项卡中,选择“对话框”,然后在“预定义选项”中选择“使用MFC的Socket”。接下来,按照默认设置完成创建。 2. 添加代码 接下来,我们需要添加一些代码来实现客户端和服务器端的功能。 2.1 服务器端代码 在服务器端,我们需要创建一个监听套接字并等待客户端连接。当客户端连接时,我们需要创建一个新的套接字来与客户端进行通信。我们还需要实现一个函数来处理客户端发送的消息并将其广播给所有连接的客户端。 首先,在服务器的头文件中添加以下代码: #pragma once #include "afxsock.h" #define WM_SOCKET WM_USER+1 class CChatServerDlg : public CDialogEx { //... private: CSocket m_ServerSocket; CSocket m_ConnectionSocket; void ProcessMessage(CString message); public: CChatServerDlg(CWnd* pParent = nullptr); // standard constructor virtual ~CChatServerDlg(); //... 接下来,在服务器的源文件中添加以下代码: BOOL CChatServerDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Create server socket m_ServerSocket.Create(1234); // Listen for incoming connections m_ServerSocket.Listen(); // Start accepting connections m_ServerSocket.Accept(m_ConnectionSocket); // Enable asynchronous message handling m_ServerSocket.AsyncSelect(WM_SOCKET, FD_READ | FD_CLOSE); return TRUE; } void CChatServerDlg::OnSocketMessage(WPARAM wParam, LPARAM lParam) { if (wParam == m_ServerSocket.m_hSocket) { // Accept incoming connection m_ServerSocket.Accept(m_ConnectionSocket); // Enable asynchronous message handling m_ConnectionSocket.AsyncSelect(WM_SOCKET, FD_READ | FD_CLOSE); } else if (wParam == m_ConnectionSocket.m_hSocket) { // Handle incoming message char buffer[1024]; int nBytes = m_ConnectionSocket.Receive(buffer, sizeof(buffer)); if (nBytes > 0) { // Convert message to CString buffer[nBytes] = '\0'; CString message(buffer); // Process message ProcessMessage(message); } else { // Close connection m_ConnectionSocket.Close(); } } } void CChatServerDlg::ProcessMessage(CString message) { // Broadcast message to all connected clients for (int i = 0; i < m_ClientSockets.GetCount(); i++) { CSocket* pSocket = m_ClientSockets.GetAt(i); pSocket->Send(message, message.GetLength()); } } 2.2 客户端代码 在客户端,我们需要创建一个套接字并连接到服务器。一旦连接成功,我们就可以发送消息给服务器并接收来自服务器的消息。 首先,在客户端的头文件中添加以下代码: #pragma once #include "afxsock.h" #define WM_SOCKET WM_USER+1 class CChatClientDlg : public CDialogEx { //... private: CSocket m_ClientSocket; public: CChatClientDlg(CWnd* pParent = nullptr); // standard constructor virtual ~CChatClientDlg(); //... 接下来,在客户端的源文件中添加以下代码: BOOL CChatClientDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Create client socket m_ClientSocket.Create(); // Connect to server m_ClientSocket.Connect(_T("127.0.0.1"), 1234); // Enable asynchronous message handling m_ClientSocket.AsyncSelect(WM_SOCKET, FD_READ | FD_CLOSE); return TRUE; } void CChatClientDlg::OnSocketMessage(WPARAM wParam, LPARAM lParam) { if (wParam == m_ClientSocket.m_hSocket) { // Handle incoming message char buffer[1024]; int nBytes = m_ClientSocket.Receive(buffer, sizeof(buffer)); if (nBytes > 0) { // Convert message to CString buffer[nBytes] = '\0'; CString message(buffer); // Display message m_MessageList.AddString(message); } else { // Close connection m_ClientSocket.Close(); } } } void CChatClientDlg::OnBnClickedSendButton() { // Get message text CString message; m_MessageInput.GetWindowText(message); // Send message to server m_ClientSocket.Send(message, message.GetLength()); // Clear message input m_MessageInput.SetWindowText(_T("")); } 3. 测试程序 现在,我们可以运行程序并测试它是否可以正常工作。首先启动服务器端,然后启动多个客户端。在客户端中输入一些消息并发送给服务器,然后观察消息是否被广播到所有连接的客户端。 注意:如果您的防火墙阻止程序运行,请确保将其添加到白名单中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

tailor_long

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

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

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

打赏作者

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

抵扣说明:

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

余额充值