ios中利用BSDSocket进行网络通信(客户端篇)
2016-08-01 13:28
375 查看
最近在学习网络编程,发现BSDSocket进行网络通信是一件比较有趣的事情,顺便记下笔记
详情如下:
- (void)createSocketClientWithURL:(NSURL*)url{
// int socket(int addressFamily, int type, int protocol)
// addressFamily:IP协议类型 AF_INET指IPV4
// type:socket的类型,一般为字节流stream(SOCK_STREAM) 或 数据报文datagram(SOCK_DGRAM)
// protocol:协议,一般填0,让OS自动选取最佳协议
// 函数返回socket的文件描述符
int socketDecriputor = socket(AF_INET, SOCK_STREAM, 0);
if (socketDecriputor == -1) {
NSLog(@"socket创建失败");
}
//通过服务器的域名得到服务器的ip地址
NSString* hostName = [url host];
NSNumber* port = [url port];
struct hostent* remoteHostEnt = gethostbyname(hostName.UTF8String);
struct in_addr* remoteInAdd = (struct in_addr*)remoteHostEnt->h_addr_list[0];
//sockaddr_in 保存要连接的服务器的相关信息
struct sockaddr_in addParamters;
addParamters.sin_family = AF_INET;
addParamters.sin_addr = *remoteInAdd;
//htons是将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为:高位字节存放在内存的低地址处
addParamters.sin_port = htons([port intValue]);
// int connect(int socketFileDescriptor, sockaddr *serverAddress, int serverAddressLength)
// socketFileDescriptor: socket 的文件描述符
// serverAddress:服务器地址
// serverAddressLength:服务器地址长度
// 连接成功返回0,失败返回 -1
int reslut = connect(socketDecriputor, (struct sockaddr *)&addParamters, sizeof(addParamters));
if (reslut == -1) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.resultStr.text = @"连接服务器失败";
}];
return;
}else{
//用于保存从网络中接收的信息
NSMutableData* data = [NSMutableData data];
BOOL waitingForData = YES;
while (waitingForData) {
const char* buffer[1024]; //数据缓存区
long len = sizeof(buffer);
long resutlLen = recv(socketDecriputor, &buffer, len, 0);
if (resutlLen == -1) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.resultStr.text = @"接收失败";
}];
return;
}
[data appendBytes:&buffer length:resutlLen];
if (resutlLen == 0) {
waitingForData = NO;
}
}
close(socketDecriputor);
NSString* resultStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// UIImage* image = [UIImage imageWithData:data];
//回到主线程刷新页面
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.resultStr.text = resultStr;
// self.imaV.image = image;
}];
}
}
注意的是,当recv函数返回值为0时,一般是对端关闭了socke连接,客户端仍然在接收。
详情如下:
- (void)createSocketClientWithURL:(NSURL*)url{
// int socket(int addressFamily, int type, int protocol)
// addressFamily:IP协议类型 AF_INET指IPV4
// type:socket的类型,一般为字节流stream(SOCK_STREAM) 或 数据报文datagram(SOCK_DGRAM)
// protocol:协议,一般填0,让OS自动选取最佳协议
// 函数返回socket的文件描述符
int socketDecriputor = socket(AF_INET, SOCK_STREAM, 0);
if (socketDecriputor == -1) {
NSLog(@"socket创建失败");
}
//通过服务器的域名得到服务器的ip地址
NSString* hostName = [url host];
NSNumber* port = [url port];
struct hostent* remoteHostEnt = gethostbyname(hostName.UTF8String);
struct in_addr* remoteInAdd = (struct in_addr*)remoteHostEnt->h_addr_list[0];
//sockaddr_in 保存要连接的服务器的相关信息
struct sockaddr_in addParamters;
addParamters.sin_family = AF_INET;
addParamters.sin_addr = *remoteInAdd;
//htons是将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为:高位字节存放在内存的低地址处
addParamters.sin_port = htons([port intValue]);
// int connect(int socketFileDescriptor, sockaddr *serverAddress, int serverAddressLength)
// socketFileDescriptor: socket 的文件描述符
// serverAddress:服务器地址
// serverAddressLength:服务器地址长度
// 连接成功返回0,失败返回 -1
int reslut = connect(socketDecriputor, (struct sockaddr *)&addParamters, sizeof(addParamters));
if (reslut == -1) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.resultStr.text = @"连接服务器失败";
}];
return;
}else{
//用于保存从网络中接收的信息
NSMutableData* data = [NSMutableData data];
BOOL waitingForData = YES;
while (waitingForData) {
const char* buffer[1024]; //数据缓存区
long len = sizeof(buffer);
long resutlLen = recv(socketDecriputor, &buffer, len, 0);
if (resutlLen == -1) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.resultStr.text = @"接收失败";
}];
return;
}
[data appendBytes:&buffer length:resutlLen];
if (resutlLen == 0) {
waitingForData = NO;
}
}
close(socketDecriputor);
NSString* resultStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// UIImage* image = [UIImage imageWithData:data];
//回到主线程刷新页面
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.resultStr.text = resultStr;
// self.imaV.image = image;
}];
}
}
注意的是,当recv函数返回值为0时,一般是对端关闭了socke连接,客户端仍然在接收。
相关文章推荐
- 利用select进行网络通信
- IOS 用封装API AsyncSocket进行网络通信
- IOS 用封装API AsyncSocket进行网络通信
- 利用WSAEventSelect进行网络通信
- IOS使用AFNetworking进行网络通信
- Android中利用httpclient进行网络通信的方法(以用户登录为例说明)
- IOS用封装的API AsyncSocket进行网络通信
- 【Linux网络编程实例】实例二:利用TCP协议进行客户端与服务器通信
- Android中利用httpclient进行网络通信的方法(以用户登录为例说明)
- IOS 用封装API AsyncSocket进行网络通信
- Android 利用httpclient进行网络通信,实现用户登录的方法
- 利用java编写网络通信程序
- 利用管道进行通信
- 利用Java实现网络通信
- 利用WinInet类进行TCP/IP通信内容
- 利用MFC的Csocket类实现网络通信
- ssh 利用 RSA 公钥进行远程认证 - [网络相关]
- Windows server 2003下实战利用MRTG进行网络监控(一)
- 利用java编写网络通信程序
- 利用java编写网络通信程序