嵌入式linux的网络编程 3 --TCP Client程序设计

               

嵌入式linux的网络编程(3)--TCP Client程序设计

CSDN2013年度博客之星评选活动开始,本人有幸入围参加评选,如果博客中的文章对你有所帮助,请为 ce123 投上宝贵一票,非常感谢!
投票地址:http://vote.blog.csdn.net/blogstaritem/blogstar2013/ce123

1.概述

 客户端主要需要完成与服务器建立连接,请求数据,应答数据等工作.从代码上来看,客户端程序有很多代码与服务器端程序类似,我们先给出一个简单的客户端源码,随后进行详细的讲解.

  1 /**************************************************************************************/  2 /*简介:TCPClient示例。                                                          */  3 /*************************************************************************************/  4 #include <stdlib.h>    5 #include <stdio.h>   6 #include <errno.h>   7 #include <string.h>   8 #include <netdb.h>   9 #include <sys/types.h>  10 #include <netinet/in.h>  11 #include <sys/socket.h>  12  13 int main(int argc, char *argv[])  14 {  15         int sockfd;  16         char buffer[1024];         17         struct sockaddr_in server_addr;   18         struct hostent *host;      19         int portnumber,nbytes;     20  21         if(argc!=3)  22         {  23                 printf("Usage:%s hostname portnumber\a\n",argv[0]);  24                 exit(1);  25         }  26  27         if((host=gethostbyname(argv[1]))==NULL)  28         {  29                 herror ("Get host name error\n");  30                 exit(1);  31         }  32  33         if((portnumber=atoi(argv[2]))<0)  34         {  35                 printf("Usage:%s hostname portnumber\a\n",argv[0]);  36                 exit(1);  37         }  38  39         /* 客户程序开始建立 sockfd描述符 */  40         if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)  41         {  42                 printf("Socket Error:%s\a\n",strerror(errno));  43                 exit(1);  44         }  45         /* 客户程序填充服务端的资料 */  46         bzero(&server_addr,sizeof(server_addr)); 47         server_addr.sin_family=AF_INET; 48         server_addr.sin_port=htons(portnumber); 49         server_addr.sin_addr=*((struct in_addr *)host->h_addr); 50         /* 客户程序发起连接请求 */ 51         if(connect(sockfd,(struct sockaddr *)(&server_addr),\ 52                                 sizeof(struct sockaddr))==-1) 53         { 54                 printf("Connect Error:%s(%d)\a\n",strerror(errno),errno); 55                 exit(1); 56         } 57         /* 连接成功了 */ 58         if((nbytes=read(sockfd,buffer,1024))==-1) 59         { 60                 printf("Read Error:%s\n",strerror(errno)); 61                 exit(1); 62         } 63         buffer[nbytes]='\0'; 64         printf("I have received:%s\n",buffer); 65  66         /* 结束通讯 */ 67         close(sockfd); 68         exit(0); 69 }
  客户端程序首先连接到服务器端,然后才能进行数据交换,在这之前就必须知道服务器的IP地址和端口号.

2.名字地址转化

 通常,人们在使用过程中都不愿意记忆冗长的IP 地址,尤其到IPv6时,地址长度多达128位,那时就更加不可能一次次记忆那么长的IP地址了.因此,使用主机名将会是很好的选择.在Linux中,同样有一些函数可以实现主机名和地址的转化,最为常见的有gethostbyname,gethostbyaddr,getaddrinfo等,它们都可以实现IPv4和IPv6的地址和主机名之间的转化.其中gethostbyname是将主机名转化为IP地址,gethostbyaddr则是逆操作,是将IP地址转化为主机名,另外getaddrinfo还能实现自动识别IPv4地址和IPv6地址.
 gethostbyname和gethostbyaddr都涉及到一个hostent的结构体,如下所示:

struct hostent{ char *h_name;  /*正式主机名*/ char **h_aliases; /*主机别名*/ int h_addrtype;  /*地址类型*/ int h_length;  /*地址长度*/ char **h_addr_list; /*指向IPv4或IPv6的地址指针数组*/}
 调用该函数后就能返回hostent结构体的相关信息.getaddrinfo函数涉及到一个addrinfo的结构体,如下所示:
struct addrinfo{ int ai_flags;  /*AI_PASSIVE,AI_CANONNAME;*/ int ai_family;  /*地址族*/ int ai_socktype; /*socket类型*/ int ai_protocol; /*协议类型*/ size_t ai_addrlen; /*地址长度*/ char *ai_canoname; /*主机名*/ struct sockaddr *ai_addr;/*socket结构体*/ struct addrinfo *ai_next;/*下一个指针链表*/}
 对hostent结构体而言,addrinfo结构体包含更多的信息.
 gethostbyname函数语法要点如下:


 如果该函数发生错误时,但全局变量errno中不存储错误代码,h_errno中存储的才是错误代码.通过herrno函数访问变量h_errno,该函数的使用与perror的用法一样,如果例子中的29行.

 此外,还可以通过gethostname函数获得本地主机的名字,返回的名字可以用于gethostbyname,该函数的声明如下:

#include <unistd.h>int gethostname(char *hostname, size_t size);
hostname: 一个指向将要存放主机名的缓冲区指针;
size:缓冲区的长度.

 getaddrinfo函数的语法要点如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值