connect()用于建立与指定socket的连接。
头文件: #include <sys/socket.h>
函数原型: int connect(int s, const struct sockaddr * name, int namelen);
参数:
s:标识一个未连接socket
namelen:sockaddr结构体的字节长度
客户端和服务端的连接方式如下:
客户端---------->(SYN)服务器端
服务器端----------->(ACK,SYN)客户端
客户端----------->(SYN)服务器端
在建立好连接后,使用send/recv来发送或接收数据不需要指定地址,但一个套接字只能connect一次。
如果客户端要和其他的服务器端通信,必须再建立一个流式套接字,重新连接。
QT_connect函数:
原型:bool QObject::connect(const QObject* sender,const char * signal,const QObject * receiver,const char * member)[static]
connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
这里用到了两个宏:SIGNAL() 和SLOT();这两个宏最后是得到一个const char*类型。
connect调用后,emit() signal会直接调用之前connect过的
SLOT函数。
SIGNAL()宏和SLOT()宏中的函数的参数一定要严格一致。
在QObject.cpp文件中可以找到connect的实现代码,下面是去除了debug代码的connect实现。
- bool QObject::connect(const QObject *sender, const char *signal,
- const QObject *receiver, const char *method,
- Qt::ConnectionType type)
- {
- {
- const void *cbdata[] = { sender, signal, receiver, method, &type };
- if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
- return true;
- }
-
- if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
- qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
- sender ? sender->metaObject()->className() : "(null)",
- (signal && *signal) ? signal+1 : "(null)",
- receiver ? receiver->metaObject()->className() : "(null)",
- (method && *method) ? method+1 : "(null)");
- return false;
- }
- QByteArray tmp_signal_name;
-
- if (!check_signal_macro(sender, signal, "connect", "bind"))
- return false;
- const QMetaObject *smeta = sender->metaObject();
- const char *signal_arg = signal;
- ++signal;
- int signal_index = smeta->indexOfSignal(signal);
- if (signal_index < 0) {
-
- tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
- signal = tmp_signal_name.constData() + 1;
-
- signal_index = smeta->indexOfSignal(signal);
- if (signal_index < 0) {
- err_method_notfound(sender, signal_arg, "connect");
- err_info_about_objects("connect", sender, receiver);
- return false;
- }
- }
-
- QByteArray tmp_method_name;
- int membcode = extract_code(method);
-
- if (!check_method_code(membcode, receiver, method, "connect"))
- return false;
- const char *method_arg = method;
- ++method;
-
- const QMetaObject *rmeta = receiver->metaObject();
- int method_index = -1;
- switch (membcode) {
- case QSLOT_CODE:
- method_index = rmeta->indexOfSlot(method);
- break;
- case QSIGNAL_CODE:
- method_index = rmeta->indexOfSignal(method);
- break;
- }
- if (method_index < 0) {
-
- tmp_method_name = QMetaObject::normalizedSignature(method);
- method = tmp_method_name.constData();
- switch (membcode) {
- case QSLOT_CODE:
- method_index = rmeta->indexOfSlot(method);
- break;
- case QSIGNAL_CODE:
- method_index = rmeta->indexOfSignal(method);
- break;
- }
- }
-
- if (method_index < 0) {
- err_method_notfound(receiver, method_arg, "connect");
- err_info_about_objects("connect", sender, receiver);
- return false;
- }
- if (!QMetaObject::checkConnectArgs(signal, method)) {
- qWarning("QObject::connect: Incompatible sender/receiver arguments"
- "\n %s::%s --> %s::%s",
- sender->metaObject()->className(), signal,
- receiver->metaObject()->className(), method);
- return false;
- }
-
- int *types = 0;
- if ((type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
- && !(types = queuedConnectionTypes(smeta->method(signal_index).parameterTypes())))
- return false;
-
- QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);
- const_cast<QObject*>(sender)->connectNotify(signal - 1);
- return true;
- }
判断连接是否已经建立:
- const void *cbdata[] = { sender, signal, receiver, method, &type };
- if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
- return true;