4.6.3 连接服务器

来源:互联网 发布:ps切换图层快捷键 mac 编辑:程序博客网 时间:2024/06/17 09:12

  在客户端连接服务器之前,没有调用bind()函数绑定套接字。在成功调用connect()函数后,该套接字被标识为绑定。这说明connect()函数可以实现对套接字的隐式绑定。

客户端在连接服务器之前需要知道它的地址和端口。该地址和端口对客户端来说应该是已知的。该程序中客户端与服务器运行在同一个主机。服务器的端口是5555,它的地址可以通过调用gethostname()gethostbyname()函数获得。

gethostname()函数用来获得主机的名字,该函数的第一个参数在函数返回时,返回指向字符缓冲区的指针,在该缓冲区内保存了该主机的名字。

gethostname()函数的返回的主机名字为参数调用gethostbyname()函数,获得一个指向hostent结构的指针。在该结构中保存有主机的地址。

hostent结构用于表示主机的名称和网络地址。由Windows Sockets分配该结构的内存空间。因此,用于应用程序决不能修改该结构或者释放该结构中成员的内存。在客户端程序中使用该结构,获取客户端的网络地址。

hostent结构定义如下。

struct hostent {

         char FAR *                  h_name;

         char FAR * FAR *       h_aliases;

         short                                     h_addrtype;

         short                                     h_length;

         char FAR * FAR *       h_addr_list;

};

q        h_name:主机正式名称。

q        h_aliases:主机别名。

q        h_addrtype:地址类型。

q        h_length:地址长度(用字节表示)。

q        h_addr_list:主机地址列表。

获得该结构有两种方法。第一种方法。使用gethostname()函数的返回值作为参数调用gethostbyname()函数,示例程序清单如下。

LPHOSTENT hostEntry;

char hostname[NAME_MAX_SIZE];

gethostname(hostname,NAME_MAX_SIZE);

hostEntry = gethostbyname(hostname);

第二种方法。使用inet_add()函数的返回值作为参数调用gethostbyaddr()函数,示例程序清单如下。

LPHOSTENT host

unsigned long addr = inet_addr("172.20.30.55");

host = gethostbyaddr((char*)&addr,sizeof(addr),2);

当连接服务器成功时,修改bConning值为TRUE。当连接失败时,调用ShowErrorMsg()函数显示调用失败的原因,然后调用ExitClient()函数,退出客户端。

客户端连接服务器的程序清单如下。

//获取主机的信息

LPHOSTENT hostEntry;

char hostname[MAX_NUM_BUF];

gethostname(hostname,MAX_NUM_BUF);                //获取主机名称

hostEntry = gethostbyname(hostname);                     //获取主机信息

if(!hostEntry)

{

         ShowErrorMsg();                                                     //显示错误信息

         return ExitClient(CLIENT_API_ERROR);            //退出

}

//设置sockaddr_in

SOCKADDR_IN addrServ;

addrServ.sin_family = AF_INET;

addrServ.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);

addrServ.sin_port = htons(SERVERPORT);

 

//连接服务器

retVal=connect(sHost,(LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));

if(SOCKET_ERROR == retVal)

{

         ShowErrorMsg();                                            //显示错误信息

         return ExitClient(CLIENT_API_ERROR);   //退出

}else{

         bConning = TRUE;                                        //连接服务器成功

}