1.Socket是个什么玩意
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)
2.长链接
在我们实际开发中,除了即时通信,如果没有特殊要求,在请求数据的时候我们可以通过get、post来请求数据,通常是这样的,我:发送一个请求http://192.123.23.2:8888 然后后面拼上你需要的参数或者放在请求body里面,然后服务器接收到请求返回给我一些数据,如果我不发送请求,服务器是不会返送给我数据的。当然有一些需求是需要一直跟服务器有数据的交换,这个时候我们就需要超链接了。
随时可以接收到服务器给我的数据
3.介绍一些函数(c语言)
3.1 socket() 函数
int socket(int domain, int type, int protocol);
- 1.domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
- 2.type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的类型有哪些?)。
- 3.protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议
3.2 gethostbyname()函数说明
struct hostent *gethostbyname(const char *name);
//这个函数的传入值是域名或者主机名,例如"www.google.cn"等等。传出值,是一个hostent的结构。如果函数调用失败,将返回NULL。
/*
返回hostent结构体类型指针
struct hostent
{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
#define h_addr h_addr_list[0]
};
*/
3.3 connect() 函数
int connect(int, const struct sockaddr *, socklen_t)
connect函数的第一个参数即为客户端的socket描述字,第二参数为服务器的socket地址,第三个参数为socket地址的长度。客户端通过调用connect函数来建立与TCP服务器的连接
不多哔哔,进入正题 (上代码)
NSString *host = @"123.2.3.1";
NSNumber *port = @8888; //?< 端口
//创建socket 返回的int 就象文件句柄一样 我们直接用这个descriptor来操作socket
int socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0);
if (socketFileDescriptor == -1) {
NSLog(@"创建失败");
return;
}
//创建一个结构体 gethostbyname函数根据域名解析出服务器的ip地址,它返回一个结构体struct hostent:
/*
* Structures returned by network data base library. All addresses are
* supplied in host order, and returned in network order (suitable for
* use in system calls).
*/
struct hostent *remotehostEnt = gethostbyname([host UTF8String]);
if (remotehostEnt == NULL) {
close(socketFileDescriptor);
NSLog(@"无法解析服务器主机名");
return;
}
//结构体指针 指向list of addresses from name server 服务器列表的第一位 即为h_addr_list[0],表示第一个地址,这个符号其实是兼容老系统而存在的
struct in_addr *remoteIndAddr = (struct in_addr *)remotehostEnt -> h_addr;
//设置socket参数
struct sockaddr_in socketParamers;
socketParamers.sin_family = AF_INET; //?< internetwork: UDP, TCP
socketParamers.sin_addr = *remoteIndAddr; //?< 主机地址
socketParamers.sin_port = htons([port intValue]);
//连接socket
int result = connect(socketFileDescriptor, (struct sockaddr *) &socketParamers, sizeof(socketParamers));
if (result == -1) {
close(socketFileDescriptor);
NSLog(@"连接失败");
return;
}
NSLog(@"连接成功");
网友评论