• 6305阅读
  • 1回复

为什么我写的聊天程序局域网可以运行,外网就连接不上 [复制链接]

上一主题 下一主题
离线cao19881125
 
只看楼主 倒序阅读 楼主  发表于: 2011-10-16
关键词: QT4网络通信
简述:
服务端,用QTcpServer类对象监听,收到一个newConnection信号后调用相应槽函数保存QTcpSocket,然后绑定QTcpSocket对象的readyRead信号,收到信号后用QDataStream读取信息并广播出去,
客户端同理,
同一个路由器的两台电脑我试过了,可以建立连接并聊天,但是我发给远在外省的同学,就连接不上,错误提示Unkonw Error,然后connection time out,为什么啊,还要设置什么吗,代码如下

服务端:
头文件

#ifndef SERVER_H
#define SERVER_H
#include<QtGui>
#include<QTcpServer>
#include<QTcpSocket>
#include<QDataStream>
#include<QAbstractSocket>
#include<QTime>
class MySocket
{

public:
    QString name;
    QTcpSocket* tsock;
    QTcpSocket**tsockAnd;
    MySocket(const QString& str,QTcpSocket*& sock):name(str),tsock(sock)
    {
        *tsockAnd=sock;
    }


};
#include<vector>
using namespace std;

class Server:public QMainWindow
{
Q_OBJECT
private:
QMenuBar *menuBar;
QMenu   *menuStart;
QAction  *actStart;
QAction  *actEnd;

QTextEdit *txt;

QTcpServer tser;
        vector<MySocket> sockAll;
int t_num;

public:
Server(QWidget*parent=0);

public slots:
void initServer();
void acceptConnection();
void sendMsg();
        void showError(QAbstractSocket::SocketError);
};


#endif
实现文件:


#include"server.h"
Server::Server(QWidget*parent):QMainWindow(parent),t_num(0)
{
resize(500,300);
move(100,100);

menuBar=new QMenuBar;
menuStart=new QMenu(tr("开始"));
actStart=new QAction(tr("启动"),menuBar);
actEnd=new QAction(tr("关闭"),menuBar);

menuBar->addMenu(menuStart);
menuStart->addAction(actStart);
menuStart->addSeparator();
menuStart->addAction(actEnd);

setMenuBar(menuBar);

txt=new QTextEdit;
setCentralWidget(txt);
connect(actStart,SIGNAL(triggered()),this,SLOT(initServer()));
connect(actEnd,SIGNAL(triggered()),this,SLOT(close()));
connect(&tser,SIGNAL(newConnection()),this,SLOT(acceptConnection()));
  
}
void Server::initServer()
{
if(tser.listen(QHostAddress("192.168.1.101"),10000))
{
  txt->append(tr("监听成功"));
}

}
void Server::acceptConnection()
{
        QTcpSocket *sockTmp=new QTcpSocket;
        sockTmp=tser.nextPendingConnection();
        connect(sockTmp,SIGNAL(readyRead()),this,SLOT(sendMsg()));
        connect(sockTmp,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(showError(QAbstractSocket::SocketError)));
        sockAll.push_back(MySocket(QString("temp"),sockTmp));
        tser.waitForNewConnection();
txt->append(tr("有用户连接"));
t_num++;

}
void Server::sendMsg()
{
QTcpSocket *sendSocket=qobject_cast<QTcpSocket*>(sender());
QDataStream in(sendSocket);
QString str;
in>>str;
        if(str==QString("ThisIsClientName"))
        {
            in>>str;
            sockAll[sockAll.size()-1].name=str;
        }
        else
        {
            QString sendStr;
            for(int i=0;i<sockAll.size();i++)
            {
                if(sockAll.tsock==sendSocket)
                {
                    QString time=QTime::currentTime().toString("hh:mm:ss");
                    sendStr=QString("%1:%2\n  %3").arg(sockAll.name).arg(time).arg(str);
                    in<<sendStr;                }
            }
            txt->append(sendStr);
            for(int i=0;i<sockAll.size();i++)
            {
                    if(sockAll.tsock!=sendSocket&&sockAll.tsock->isValid())
                    {
                            QDataStream out(sockAll.tsock);
                            out<<sendStr;
                    }            }
        }
}
void Server::showError(QAbstractSocket::SocketError socketError)
{
    QTcpSocket* sockSend=qobject_cast<QTcpSocket*>(sender());
    if(socketError==QTcpSocket::RemoteHostClosedError)
    {
        txt->append(tr("有用户退出"));
        for(int i=0;i<sockAll.size();i++)
        {
            if(sockAll.tsock==sockSend)
            {
                delete *(sockAll.tsockAnd);
            }
        }
    }
}

客户端:
头文件:
#ifndef SERVER_H
#define SERVER_H
#include<QtGui>
#include<QTcpSocket>
#include<QDataStream>
class Client:public QMainWindow
{
Q_OBJECT
private:
QMenuBar *menuBar;
QMenu *menuStart;
QAction *actStart;
QAction *actEnd;

QWidget *wd;
QTextEdit *txt;
QLineEdit *line;
QPushButton *btnSend;
QTcpSocket *tsock;
        QString strName;
public:
Client(QWidget*parent=0);
public slots:
void linkToHost();
void sendMsg();
void showConnect();
void showMsg();
        void showSocketError(QAbstractSocket::SocketError);
};
#endif
实现文件:
#include"client.h"
#include<QHostAddress>
Client::Client(QWidget*parent):QMainWindow(parent)
{
resize(300,500);
move(100,100);
  
menuBar=new QMenuBar;
menuStart=new QMenu(tr("开始"));
actStart=new QAction(tr("连接"),menuStart);
actEnd=new QAction(tr("退出"),menuStart);
  
menuBar->addMenu(menuStart);
menuStart->addAction(actStart);
menuStart->addSeparator();
menuStart->addAction(actEnd);

setMenuBar(menuBar);

wd=new QWidget;
txt=new QTextEdit;
btnSend=new QPushButton;
btnSend->setText(tr("发送"));
        btnSend->setEnabled(false);
line=new QLineEdit;

QHBoxLayout *hb=new QHBoxLayout;
hb->addWidget(line);
hb->setSpacing(5);
hb->addWidget(btnSend);

QVBoxLayout *vb=new QVBoxLayout;
vb->addWidget(txt);
vb->setSpacing(10);
vb->addLayout(hb);

wd->setLayout(vb);
setCentralWidget(wd);

connect(actStart,SIGNAL(triggered()),this,SLOT(linkToHost()));
connect(actEnd,SIGNAL(triggered()),this,SLOT(close()));
connect(btnSend,SIGNAL(clicked()),this,SLOT(sendMsg()));
}
void Client::linkToHost()
{    bool ok;
    strName=QInputDialog::getText(this,tr("输入对话框"),tr("输入用户名"),
                                            QLineEdit::Normal,"",&ok);
    if(ok&&!strName.isEmpty())
    {
        tsock=new QTcpSocket;
        tsock->connectToHost(QHostAddress("192.168.1.101"),10000);
        connect(tsock,SIGNAL(connected()),this,SLOT(showConnect()));
        connect(tsock,SIGNAL(readyRead()),this,SLOT(showMsg()));
        connect(tsock,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(showSocketError(QAbstractSocket::SocketError)));
    }
    else
    {
        QMessageBox::warning(this,tr("警告"),tr("用户名为空"),QMessageBox::Yes);
    }
}
void Client::sendMsg()
{
QString str;
str=line->text();

QDataStream out(tsock);
        if(!str.isEmpty()&&tsock->isValid())
{
  out<<str;
}
}
void Client::showConnect()
{    txt->append(tr("连接成功"));
    btnSend->setEnabled(true);
    QDataStream out(tsock);
    out<<QString("ThisIsClientName");
    out<<QString(strName); }
void Client::showMsg()
{
QDataStream in(tsock);
QString str;
in>>str;
txt->append(str);
        txt->append(" ");
}
void Client::showSocketError(QAbstractSocket::SocketError sockError)
{
    txt->append(tr("连接错误:%1").arg(tsock->errorString()));
}
求指教啊 。。。。。。。。。。。。。。。
爱QT,爱C++,爱生活
离线wxj120bw

只看该作者 1楼 发表于: 2011-10-19
回 楼主(cao19881125) 的帖子
你先确认你外地的朋友能通192.168.1.101这个地址吗 区别内网地址和外网地址
快速回复
限100 字节
 
上一个 下一个