socket
-
查看端口 lsof -i:8040
-
杀掉端口 kill -9 17870
-
socket 是一个抽象层的API,具备双向性
-
127.0.0.1 和本地回环地址进行通讯
终端 拦截代理
- nc -l 8040
c: missing hostname and port
usage: nc [-46AacCDdEFhklMnOortUuvz] [-K tc] [-b boundif] [-i interval] [-p source_port]
[--apple-recv-anyif] [--apple-awdl-unres]
[--apple-boundif ifbound]
[--apple-no-cellular] [--apple-no-expensive]
[--apple-no-flowadv] [--apple-tcp-timeout conntimo]
[--apple-tcp-keepalive keepidle] [--apple-tcp-keepintvl keepintvl]
[--apple-tcp-keepcnt keepcnt] [--apple-tclass tclass]
[--tcp-adp-rtimo num_probes] [--apple-initcoproc-allow]
[--apple-tcp-adp-wtimo num_probes]
[--setsockopt-later] [--apple-no-connectx]
[--apple-delegate-pid pid] [--apple-delegate-uuid uuid]
[--apple-kao] [--apple-ext-bk-idle]
[--apple-netsvctype svc] [---apple-nowakefromsleep]
[--apple-notify-ack] [--apple-sockev]
[--apple-tos tos] [--apple-tos-cmsg]
[-s source_ip_address] [-w timeout] [-X proxy_version]
[-x proxy_address[:port]] [hostname] [port[s]]
解释
目的主机监听
nc -l 监听端口<未使用端口> > 要接收的文件名
nc -l 4444 > cache.tar.gz
源主机发起请求
nc 目的主机ip 目的端口 < 要发送的文件
nc 192.168.0.85 4444 < /root/cache.tar.gz
netstat 如下
netstat -tpln
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 18166/nc
英文描述如下
DATA TRANSFER
Start by using nc to listen on a specific port, with output captured into a file:
$ nc -l 1234 > filename.out
Using a second machine, connect to the listening nc process, feeding it the file which is to be transferred:
$ nc host.example.com 1234 < filename.in
另附nc的其他选项说明:
语 法:nc [-hlnruz][-g<网关...>][-G<指向器数目>][-i<延迟秒数>][-o<输出文件>][-p<通信端口>][-s<来源位址>][-v...][-w<超时秒数>][主机名称][通信端口...]
补充说明:执行本指令可设置路由器的相关参数。
参 数:
-g<网关> 设置路由器跃程通信网关,最丢哦可设置8个。
-G<指向器数目> 设置来源路由指向器,其数值为4的倍数。
-h 在线帮助。
-i<延迟秒数> 设置时间间隔,以便传送信息及扫描通信端口。
-l 使用监听模式,管控传入的资料。
-n 直接使用IP地址,而不通过域名服务器。
-p<通信端口> 设置本地主机使用的通信端口。
-r 乱数指定本地与远端主机的通信端口。
-s<来源位址> 设置本地主机送出数据包的IP地址。
-u 使用UDP传输协议。
-v 显示指令执行过程。
-w<超时秒数> 设置等待连线的时间。
-z 使用0输入/输出模式,只在扫描通信端口时使用
- socket 参数描述
/**
1: 创建socket
参数
domain:协议域,又称协议族(family)。常用的协议族有AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域Socket)、AF_ROUTE等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
type:指定Socket类型。常用的socket类型有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等。流式Socket(SOCK_STREAM)是一种面向连接的Socket,针对于面向连接的TCP服务应用。数据报式Socket(SOCK_DGRAM)是一种无连接的Socket,对应于无连接的UDP服务应用。
protocol:指定协议。常用协议有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
注意:1.type和protocol不可以随意组合,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当第三个参数为0时,会自动选择第二个参数类型对应的默认协议。
返回值:
如果调用成功就返回新创建的套接字的描述符,如果失败就返回INVALID_SOCKET(Linux下失败返回-1)
*/
自定义socket实现
- 库
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
步骤一:定义IP地址和端口
#define SocketPort htons(8040)
#define SocketIP inet_addr("127.0.0.1")
步骤二:创建socket对象
int socketID = socket(AF_INET, SOCK_STREAM, 0);
self.clinenId= socketID;
if (socketID == -1) {
NSLog(@"创建socket 失败");
return;
}
步骤三:将端口和地址 赋值给socket api
// 端口
struct sockaddr_in socketAddr;
socketAddr.sin_family = AF_INET;
socketAddr.sin_port = SocketPort;
// IP
struct in_addr socketIn_addr;
socketIn_addr.s_addr = SocketIP;
// 端口 绑定 IP(小尾顺序)
socketAddr.sin_addr = socketIn_addr;
步骤四:连接 connect
/**
参数
参数一:套接字描述符
参数二:指向数据结构sockaddr的指针,其中包括目的端口和IP地址
参数三:参数二sockaddr的长度,可以通过sizeof(struct sockaddr)获得
返回值
成功则返回0,失败返回非0,错误码GetLastError()。
*/
int result = connect(socketID, (const struct sockaddr *)&socketAddr, sizeof(socketAddr));
if (result != 0) {
NSLog(@"链接失败");
return;
}
NSLog(@"链接成功");
// 在异步子线程中循环接收消息
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self recvMsg];
});
- [self recvMsg]
-(void)recvMsg{
NSLog(@"来到了接受消息");
// 4. 接收数据
/**
参数
1> 客户端socket
2> 接收内容缓冲区地址
3> 接收内容缓存区长度
4> 接收方式,0表示阻塞,必须等待服务器返回数据
返回值
如果成功,则返回读入的字节数,失败则返回SOCKET_ERROR
*/
while (1) {
uint8_t buffer[1024];
ssize_t recvLen = recv(self.clinenId, buffer, sizeof(buffer), 0);
// 当没有接收到消息的时候会阻塞在这里不会往下执行,处理完消息进入循环继续阻塞
if (recvLen == 0) {
// 容错判断:如果消息为空,啥也不做,进入循环开启阻塞
NSLog(@"接收到了0个字节");
continue;
}
// buffer -> data -> string
NSData *data = [NSData dataWithBytes:buffer length:recvLen];
NSString *str= [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@---%@",[NSThread currentThread],str);
dispatch_async(dispatch_get_main_queue(), ^{
// 1 接收来自服务端的消息
[self showMsg:str msgType:1];
self.sendMsgContent_tf.text = @"";
});
}
}
步骤五:客户端发送消息
/**
发送消息
s:一个用于标识已连接套接口的描述字。
buf:包含待发送数据的缓冲区。
len:缓冲区中数据的长度。
flags:调用执行方式。
返回值
如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR
一个中文对应 3 个字节!UTF8 编码!
*/
if (self.sendMsgContent_tf.text.length == 0) {
return;
}
// 处理输入文本框的内容
const char *msg = self.sendMsgContent_tf.text.UTF8String;
// 发送消息到服务端
ssize_t sendLen = send(self.clinenId, msg, strlen(msg), 0);
NSLog(@"发送 %ld 字节",sendLen);
// 处理消息并且在文本框显示
[self showMsg:self.sendMsgContent_tf.text msgType:0];
// 清除文本框
self.sendMsgContent_tf.text = @"";
步骤六:处理消息显示到文本视图UITextView
- 补充:这个TextView不一般,绝不是大家所想象的简单的现实文本,为啥呢->自己研究文档
这里是简单的富文本处理
- (void)showMsg:(NSString *)msg msgType:(int)msgType{
// 发送消息0 接收消息1
// 时间处理
NSString *showTimeStr = [self getCurrentTime];
if (showTimeStr) {
NSMutableAttributedString *dateAttributedString = [[NSMutableAttributedString alloc] initWithString:showTimeStr];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
// 对齐方式
paragraphStyle.alignment = NSTextAlignmentCenter;
[dateAttributedString addAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:13],NSForegroundColorAttributeName:[UIColor blackColor],NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, showTimeStr.length)];
[self.totalAttributeStr appendAttributedString:dateAttributedString];
[self.totalAttributeStr appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@"\n"]];
}
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.headIndent = 20.f;
NSMutableAttributedString *attributedString;
if (msgType == 0) { // 我发送的
attributedString = [[NSMutableAttributedString alloc] initWithString:msg];
paragraphStyle.alignment = NSTextAlignmentRight;
[attributedString addAttributes:@{
NSFontAttributeName:[UIFont systemFontOfSize:15],
NSForegroundColorAttributeName:[UIColor whiteColor],
NSBackgroundColorAttributeName:[UIColor blueColor],
NSParagraphStyleAttributeName:paragraphStyle
}
range:NSMakeRange(0, msg.length)];
}else{
msg = [msg substringToIndex:msg.length];
attributedString = [[NSMutableAttributedString alloc] initWithString:msg];
[attributedString addAttributes:@{
NSFontAttributeName:[UIFont systemFontOfSize:15],
NSForegroundColorAttributeName:[UIColor blackColor],
NSBackgroundColorAttributeName:[UIColor whiteColor],
NSParagraphStyleAttributeName:paragraphStyle
}
range:NSMakeRange(0, msg.length)];
}
[self.totalAttributeStr appendAttributedString:attributedString];
[self.totalAttributeStr appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@"\n"]];
self.allMsgContent_tv.attributedText = self.totalAttributeStr;
}
步骤七:[self getCurrentTime]
- (NSString *)getCurrentTime{
NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *dateStr = [dateFormatter stringFromDate:date];
if (!self.recoderTime || self.recoderTime.length == 0) {
self.recoderTime = dateStr;
return dateStr;
}
NSDate *recoderDate = [dateFormatter dateFromString:self.recoderTime];
self.recoderTime = dateStr;
NSTimeInterval timeInter = [date timeIntervalSinceDate:recoderDate];
NSLog(@"%@--%@ -- %f",date,recoderDate,timeInter);
if (timeInter<30) {
return @" ";
}
return dateStr;
}
- 补充
大端 & 小端
- 判断系统时大端还是小端
#include <</SPAN>stdio.h>
#include <</SPAN>stdlib.h>
int main(void)
{
short int a = 0x1234;
char *p = (char *)&a;
printf("p=%#hhx\n", *p);
if (*p == 0x34) {
printf("little endian\n");
} else if (*p == 0x12) {
printf("big endia\n");
} else {
printf("unknown endia\n");
}
return 0;
}
socket server 篇章明天发布
网友评论