관리 메뉴

Value Creator의 IT(프로그래밍 / 전자제품)

#11 QT 네트워크 소켓 프로그래밍 해석 본문

1. 프로그래밍/3) QT

#11 QT 네트워크 소켓 프로그래밍 해석

valuecreatort 2019. 6. 17. 17:34
반응형

m_socket = new QSocket(this);

QObject::connect(m_socket, SIGNAL(connected()), this, SLOT(slotConneted()));

QObject::connect(m_socket, SIGNAL(connectionClosed()), this, SLOT(slotDisconnected()));

QObject::connect(m_socket, SIGNAL(error(int)), this, SLOT(slotError(int)));

QObject::connect(m_socket, SIGNAL(readyRead()), this, SLOT(slotRead()));

 

QT는 기본적으로 SIGNAL과 SLOT 형식을 많이 사용하기 때문에 SIGNAL-SlOT형식인 connect로 표현하면

1) SIGNAL : 연결이 들어오면 → SLOT : 연결을 한다.

2) SIGNAL : 연결을 끊으면 → SLOT : 연결을 끊는다.

3) SIGNAL : 에러가 생기면 → SLOT : 에러를 표시한다.

4) SIGNAL : 준비가 되면 → SLOT : 준비한다.

 

호스트에서는

QString host = m_host->text();

int port = m_port->value();

m_socket -> connectToHost(host, port);

1) 호트트 연결 소스코드

2) QSocket은 ::connectToHost로 연결을 시작하고 그 후 즉시 반환합니다.

3) 첫번째 파라미터는 지정 될 수 있는 IP 주소 또는 호스트 이름이 될 수 있습니다.

 

 

QString input = m_input->text();

 

if (input.isEmpty())

return;

 

if (m_socket->state() == QSocket::Connected)

{

QTextStream stream(m_socket);

stream << input << endl;

}

 

1) 이 소켓이 접속할것인지 소스코드..

2) 소켓을 통해 텍스트라인을 보낼지 여부를 확인합니다. 비어잇으면 그냥 리턴, 소켓이 연결되면 QTextStream을 거쳐 input으로 출력합니다.

 

 

 

 

QString text;

while (m_socket->canReadLine())

text += m_socket->readLine();

1) 연결 슬롯에 해당하는 코드

2) readyread 소켓의 접속 신호 . 이것은 항상 새로운 데이터가 전송되어 소켓에 도착되는 신호.

 

void ServerSocket::newConnection(int socketfd)

{

QSocket* socket = new QSocket(parent());

 

socket->setSocket(socketfd);

 

emit newClient(socket);

}

 

1) 서버연결

 

class Client

{

 

public:

Client(QSocket* socket, QListViewItem* item): m_socket(socket), m_item(item), m_num(++m_count)

{

 

};

 

~Client() {

delete m_socket;

delete m_item;

}

 

inline QSocket* socket() { return m_socket; }

 

inline QListViewItem* item() { return m_item; }

 

inline int number() { return m_num; }

 

protected:

static int m_count;

QSocket* m_socket;

QListViewItem* m_item;

int m_num;

 

};

 

1) 헤더파일 에 해당하는 부분

2) 자동삭제는 m_clients.setAutoDelete (TRUE); 추가

 

void ServerMainWindow::sendToClients(const QString& text)

{

if (text.isNull()) return;

 

// iterate over all clients and send them the text

QPtrDictIterator<Client> iter(m_clients);

for (; iter.current() != 0; ++iter)

{

QSocket* sock = iter.current()->socket();

QTextStream stream(sock);

stream << text;

}

}

 

1) 경로의 모든 항목을 해결하기 위해 반복자 사용시 코드

 

 

m_server = new ServerSocket(m_port->value(), this);

if (!m_server->ok())

{

delete m_server;

m_server = 0;

return;

}

 

QObject::connect(m_server, SIGNAL(newClient(QSocket*)), this, SLOT(slotNewClient(QSocket*)));

1) 바인드() 호출이 성공하면 QServerSocket 함수는 ture를 반환 , 그렇지않으면 false

 

QListViewItem* item = new QListViewItem(m_list, socket->peerAddress().toString(),

QString::number(socket->peerPort()));

Client* client = new Client(socket, item);

 

// notify all others about the newcomer

sendToClients(QString("Server: Client %0 connected\n").arg(client->number()));

 

m_clients.insert(socket, client);

 

QObject::connect(socket, SIGNAL(connectionClosed()), this, SLOT(slotClientDisconnected()));

QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(slotSocketRead()));

 

// great the newcomer

QTextStream stream(socket);

stream << "Server: Hi\nYou are client " << client->number() << endl;

1) GUI에서 연결을 보여주는 리스트 뷰 항목을 만든다. 내부적으로 사용하는 경우 클라이언트 프로그램에서QSocket의 수신에 해당 슬롯으로 신호를 데이터 분리 처리 할 수 잇다. 링크 파트너는 그 자체로 연결이 종료되고, 단부에 소켓을 보내는 경우 연결이 종료 신호를 출력한다.

 

QObject* sender = const_cast<QObject*>(QObject::sender());

QSocket* socket = static_cast<QSocket*>(sender);

 

qDebug("client disconnected");

 

//disconnect signals

socket->disconnect();

 

// remove from dict

Client* client = m_clients.take(socket);

 

sendToClients(QString("Server: Client %0 disconnected\n").arg(client->number()));

 

delete client;

 

1) 하나의 슬롯에 연결된 모든 클라이언트 소켓의 신호를 가지고 있기 때문에, 처음 발송 신호를 가지고 있는 소켓을 알아야 합니다. QOBject를 통해 보낸사람을 알수 있다.

2) take()는 경로에서 엔트리를 삭제 하지 않고 자동삭제한다. 먼저 우리가 자동삭제를 허용했기 때문에 가능.

3) 수신 데이터가 클라이언트 프로그램과 유사하게 취급됨.

 

 

QObject* sender = const_cast<QObject*>(QObject::sender());

QSocket* socket = static_cast<QSocket*>(sender);

 

Client* client = m_clients.find(socket);

 

while (socket->canReadLine())

{

QString line = socket->readLine(); // read the line of text

 

// and send it to everone including the sender

sendToClients(QString("Client %0: %1").arg(client->number()).arg(line));

 

client->item()->setText(2, line.left(line.length

 

반응형
Comments