m0_73909606 2023-02-18 14:31 采纳率: 100%
浏览 55
已结题

写了一个socket通信程序(能在一台电脑上连接成功,但同一局域网下两台电脑却不能连接)

Socket Client和Server在自己电脑上都能连接成功,但换成两台电脑就连不上了:
server:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <Windows.h>
#include <list>
#include <thread>
#include<string>
#include <iostream>
#pragma comment(lib,"ws2_32")
using namespace std;
int main()
{
    WSADATA data;
    int ret = WSAStartup(MAKEWORD(2, 2), &data);
    if (ret)
    {
        cout << "初始化网络错误!" << endl;
        WSACleanup();
        return -1;
    }
    SOCKET sockSev = socket(AF_INET, SOCK_STREAM, 0);
    if (sockSev == -1)
    {
        cout << "创建套接字失败!";
        WSACleanup();
        return -1;
    }
    sockaddr_in addrSev;
    addrSev.sin_family = AF_INET;
    addrSev.sin_port = htons(9999);
    addrSev.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    ret = bind(sockSev, (sockaddr*)&addrSev, sizeof(addrSev));
    if (ret == -1)
    {
        cout << "绑定地址端口失败!";
        WSACleanup();
        return -1;
    }
    ret = listen(sockSev, 5);
    if (ret == -1)
    {
        cout << "监听套接字失败!";
        WSACleanup();
        return -1;
    }
    list<SOCKET> listSock;
    while (true)
    {
        cout << "等待用户连接" << endl;
        sockaddr_in addrCli;
        char buf[0xFF]="连接服务器成功!";
        char kind[0xFF] = "0";
        int len = sizeof(addrCli);
        SOCKET sockCli = accept(sockSev, (sockaddr*)&addrCli, &len);
        if (sockCli == INVALID_SOCKET)
        {
            cout << inet_ntoa(addrCli.sin_addr) << "连接失败!" << endl;
            closesocket(sockCli);
            break;
        }
        else
        {
            cout << "检测到:socket:" << sockCli << "ip:" << inet_ntoa(addrCli.sin_addr) << endl;
            listSock.push_back(sockCli);
            int rett = send(sockCli, kind, 0xFF, 0);
            ret = send(sockCli, buf, 0xFF, 0);
            if (ret == -1||rett==-1)
            {
                cout << "连接失败" << endl;
                break;
            }
            thread t([&listSock]()
                {
                    char tkind[0xFF]="1";
                    string name;
                    int ret;
                    char buf[0xFF];
                    SOCKET sockCli = listSock.back();
                    auto begin = listSock.begin();
                    auto end = listSock.end();
                    ret = recv(sockCli, buf, 0xFF, 0);
                    if (ret <= 0) return;
                    name = buf;
                    string infor = name+" 进入了服务器";
                    for (; begin != end; begin++)
                    {
                        if (*begin != sockCli)
                        {
                            int rett= send(*begin, tkind , sizeof(buf), 0);
                            ret = send(*begin, infor.data(), sizeof(buf), 0);
                            if (ret == -1||rett==-1)
                            {
                                cout << "发送信息失败!" << endl;
                                break;
                            }
                        }
                    }
                    while (true)
                    {
                        begin = listSock.begin();
                        end = listSock.end();
                        char buf[0xFF];
                        ret = recv(sockCli, buf, 0xFF, 0);
                        if (ret <=0)
                        {
                            //cout << "接收客户端数据失败!"<<endl;
                            break;
                        }
                        cout << "socket:" << sockCli << ":" << buf << endl;
                        string b = ":";
                        string msg = name + b + buf;
                        for (; begin != end; begin++)
                        {
                            if (*begin != sockCli)
                            {
                                char kind[0xFF] = "0";
                                int rett = send(*begin, kind, sizeof(buf), 0);
                                ret = send(*begin,msg.data(), sizeof(buf), 0);
                                if (ret == -1||rett==-1)
                                {
                                    cout << "发送信息失败!" << endl;
                                    break;
                                }
                            }
                        }
                    }
                    closesocket(sockCli);
                    listSock.remove(sockCli);
                    cout << "有人离开了服务器" << endl;
                });
            t.detach();
            //system("pause");
        }
    }
    closesocket(sockSev);
    WSACleanup();
    system("pause");
    return 0;
}

client:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <thread>
#include <list>
#include <fstream>
#include <conio.h>
#include <Windows.h>
#include <string>
#include <mutex>
#include <iostream>
#pragma comment(lib,"ws2_32")

using namespace std;
std::mutex mut;
int mssg;
int member = 0;
list<string> listname;
int ok = false;
void gotoxy(short x, short y)//用于移动光标,更改其位置
{
    COORD coord = { x, y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void Draw()
{
    for (int i = 0; i < 32; i++)
    {
        gotoxy(80, i); cout << "■";
    }
    gotoxy(82, 0); cout << "当前在线人数:" << member;
    auto begin = listname.begin();
    auto end = listname.end();
    for (int i=0; begin!=end; begin++,i++)
    {
        gotoxy(82, i + 1);
        cout << *begin;
    }
    gotoxy(0, 30);
}
int main()
{
    mssg = 0;
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;
    GetConsoleMode(hStdin, &mode);
    mode &= ~ENABLE_QUICK_EDIT_MODE;
    SetConsoleMode(hStdin, mode);//取消快速编辑
    system("mode con cols=116 lines=32");
    Draw();
    string name;
    WSADATA data;
    int ret = WSAStartup(MAKEWORD(2, 2), &data);
    if (ret)
    {
        cout << "初始化网络错误!" << endl;
        WSACleanup();
        return -1;
    }
    fstream fp;
    fp.open("./name.txt", ios::in);
    if (fp.is_open() == false)
    {
        cout << "初次登录,请输入昵称:" << endl;
        fp.open("./name.txt", ios::out|ios::app);
        cin >> name;
        fp << name;
        fp.close();
    }//没登过就先输昵称
    else
    {
        getline(fp, name);
        fp.close();//从文件中提取昵称
    }
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);
    addr.sin_addr.S_un.S_addr = inet_addr("10.69.121.32");
    ret = connect(sock, (sockaddr*)&addr, sizeof(addr));
    if (ret == -1)
    {
        cout << "连接服务器失败!" << endl;
        WSACleanup();
        int err=WSAGetLastError();
        cout << err << endl;
        system("pause");
        return -1;
    }
    gotoxy(0, mssg);
    cout << "欢迎:" << name;
    mssg++;
    //cout << "服务器连接成功" << endl;
    thread t([&sock]()
        {
            while (true)
            {
                char buf[0xFF];
                char kind[0xFF];
                int rett = recv(sock, kind, 0xFF, 0);
                int ret = recv(sock, buf, 0xFF, 0);
                if (ret <= 0||rett<=0)
                {
                    cout << "服务器已断联"<<endl;
                    break;
                }
                gotoxy(0, mssg);
                string tkind = kind;
                cout <<tkind<<"-"<< buf << endl;
                mssg++;//接收服务器信息
                if (mssg > 30)
                {
                    system("cls"); Draw();
                    mssg = 0;
                }
                if (tkind == "1")
                {
                    member++;
                    gotoxy(82, 0); cout << "当前在线人数:" << member;
                    string men = buf;
                    size_t p=men.find(" ");
                    string tname = men.substr(0, p);
                    listname.push_back(tname);
                    gotoxy(82, member); cout << tname;
                }
                gotoxy(0, 30);
            }
        });
    t.detach();
    ret = send(sock, name.data(), sizeof(name), 0);
    if (ret == -1)
    {
        cout << "昵称上传出错" << endl;
        WSACleanup();
        return -1;
    }
    member++;
    listname.push_back(name);
    gotoxy(82, 0); cout << "当前在线人数:" << member;
    gotoxy(82, member); cout << name;
    ok = true;
    string msg;
    while (true)
    {
        cin >> msg;
        ok = true;
        ret = send(sock, msg.data(), sizeof(msg), 0);
        if (ret == -1)
        {
            cout << "发送服务器数据失败!" << endl;
            break;
        }
        gotoxy(0, mssg); cout << msg;
        gotoxy(0, 30);
        for (int i = 0; i < 80; i++) cout << " ";
        gotoxy(0, 30);
        mssg++;
        if (mssg > 30)
        {
            system("cls"); Draw();
            mssg = 0;
        }
    }
    closesocket(sock);
    WSACleanup();
}

在网上搜寻了好久依旧没有头绪,求解答,非常感谢!

  • 写回答

2条回答 默认 最新

  • WZZNB666 2023-02-18 14:55
    关注

    这个问题可能是因为在同一局域网下,服务器和客户端的IP地址不正确而导致的。首先要确保两台电脑连接到同一个局域网,并且可以相互访问。然后需要确认服务器程序中监听的IP地址是否为本机的IP地址,而不是绑定在“localhost”上。可以通过以下代码修改为本机IP地址进行监听:

    addrSev.sin_addr.S_un.S_addr = inet_addr("服务器IP地址");
    
    

    另外,客户端连接服务器时需要指定服务器的IP地址。可以通过以下代码设置服务器的IP地址:

    sockaddr_in addrSrv;
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(9999);
    addrSrv.sin_addr.S_un.S_addr = inet_addr("服务器IP地址");
    
    

    确保服务器IP地址设置正确后,再在客户端上连接即可。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 2月27日
  • 已采纳回答 2月19日
  • 创建了问题 2月18日

悬赏问题

  • ¥50 gki vendor hook
  • ¥15 centos7中sudo命令无法使用
  • ¥15 灰狼算法和蚁群算法如何结合
  • ¥15 这是一个利用ESP32自带按键和LED控制的录像代码,编译过程出现问题,请解决并且指出错误,指导如何处理 ,协助完成代码并上传代码
  • ¥20 stm32f103,hal库 hal_usart_receive函数接收不到数据。
  • ¥20 求结果和代码,sas利用OPTEX程序和D-efficiency生成正交集
  • ¥50 adb连接不到手机是怎么回事?
  • ¥20 抓取数据时发生错误: get_mooncake_data() missing 1 required positional argument: 'driver'的问题,怎么改出正确的爬虫代码?
  • ¥15 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联