socket基于tcp客户端实例

socket基于tcp客户端实例

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

#define DEFAULT_PORT 4000
#define MAXLINE 4096

// 全局变量
pthread_t worker_thread = 0;          // 工作线程 ID
volatile int thread_running = 0;      // 线程运行状态
volatile int thread_should_exit = 0;  // 线程退出标志
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  // 互斥锁

// 线程清理函数
void cleanup_handler(void *arg) {
    printf("Thread: Cleaning up resources...\n");
}

// 工作线程函数
void *receive_file(void *arg) {
    printf("Thread: Entered thread\n");

    // 注册清理函数
    pthread_cleanup_push(cleanup_handler, NULL);

    while (!thread_should_exit) {
        // 模拟工作
        printf("Thread: Working...\n");
        sleep(1);
    }

    // 清理
    pthread_cleanup_pop(1);
    printf("Thread: Exiting...\n");
    return NULL;
}

// 创建线程
void create_thread() {
    pthread_mutex_lock(&mutex);
    if (!thread_running) {
        thread_should_exit = 0;  // 重置退出标志
        int ret = pthread_create(&worker_thread, NULL, receive_file, NULL);
        if (ret != 0) {
            perror("pthread_create");
            exit(EXIT_FAILURE);
        }
        thread_running = 1;
        printf("Main: Created thread\n");
    } else {
        printf("Main: Thread is already running\n");
    }
    pthread_mutex_unlock(&mutex);
}

// 销毁线程
void destroy_thread() {
    pthread_mutex_lock(&mutex);
    if (thread_running) {
        printf("Main: Stopping thread...\n");
        thread_should_exit = 1;  // 设置退出标志

        // 等待线程退出并回收资源
        int ret = pthread_join(worker_thread, NULL);
        if (ret != 0) {
            perror("pthread_join");
            exit(EXIT_FAILURE);
        }

        thread_running = 0;
        printf("Main: Thread has exited.\n");
    } else {
        printf("Main: No thread is running\n");
    }
    pthread_mutex_unlock(&mutex);
}

// 解析 16 进制输入
int parse_hex_input(const char *input, unsigned char *output, size_t output_size) {
    char *endptr;
    for (size_t i = 0; i < output_size; i++) {
        output[i] = (unsigned char)strtol(input + 2 * i, &endptr, 16);
        if (endptr != input + 2 * (i + 1)) {
            return -1;  // 非法输入
        }
    }
    return 0;
}

int main(int argc, char *argv[]) {
	int i = 0;
	int input = 0;
    int sockfd;
    struct sockaddr_in servaddr;

    // 检查命令行参数
    if (argc != 2) {
        printf("Usage: %s <ipaddress>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // 创建 Socket
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("Create socket error: %s (errno: %d)\n", strerror(errno), errno);
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(DEFAULT_PORT);
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
        printf("inet_pton error for %s\n", argv[1]);
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // 连接到服务器
    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        printf("Connect error: %s (errno: %d)\n", strerror(errno), errno);
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    printf("Connected to server at %s:%d\n", argv[1], DEFAULT_PORT);

    // 主循环
    while (1) {
        unsigned char input_buf[8] = {0};
        char input_str[17];  // 8 个 16 进制数,每个占 2 字符,加上结束符

        for (i = 0; i < 8; i++) {
			scanf("%x", &input);
			input_buf[i] = input;
		}

        // 打印输入
        printf("Input: ");
        for (int i = 0; i < 8; i++) {
            printf("%02X ", input_buf[i]);
        }
        printf("\n");

        // 根据输入启动或停止线程
        if (input_buf[0] == 0xFA && input_buf[7] == 0x01) {
            create_thread();
        } else if (input_buf[0] == 0xFA && input_buf[7] == 0x02) {
            destroy_thread();
        }
    }

    // 清理资源
    destroy_thread();  // 确保线程退出
    pthread_mutex_destroy(&mutex);
    close(sockfd);

    return 0;
}