socket client 篇章

2022-07-12  本文已影响0人  f8d1cf28626a

socket

终端 拦截代理

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输入/输出模式,只在扫描通信端口时使用
/**
     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];
    });
-(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

这里是简单的富文本处理

- (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 篇章明天发布

上一篇 下一篇

猜你喜欢

热点阅读