TCP-client客户端代码

第一版

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>     // 包含套接字函数库
#include <netinet/in.h>     // 包含AF_INET相关结构
#include <arpa/inet.h>      // 包含AF_INET相关操作函数
#include <unistd.h>
#include <stdlib.h>         // exit()

#define PORT 8085

int main(int argc, char *argv[])
{
    int sock_fd;
    int len;
    struct sockaddr_in addr;
    int newsock_fd;
    char * buf = "come on";
    int len2;
    char rebuf[40];

    sock_fd = socket(AF_INET, SOCK_STREAM, 0);  // 创建套接字
    addr.sin_family = AF_INET;                  // 表示TCP/IP协议簇
    // 为什么是本机IP填入到客户端的套接字,客户端需要IP嘛?客户端不需要绑定bind,程序自动分配位占用的端口
    // ---》应该是远端主机的IP地址和端口号,测试是同一台主机,所以填INADDR_ANY
    //addr.sin_addr.s_addr = htonl(INADDR_ANY);   // 32位值从主机字节序转为网络字节序
    addr.sin_addr.s_addr = inet_addr("10.3.119.141");
    addr.sin_port = htons(PORT);                       // 需要连接的端口号
    len = sizeof(addr);                         // 套接字的长度

    // 参数:函数返回的套接字描述符,含远端主机IP和port的指针,远端地址结构的长度
    newsock_fd = connect(sock_fd, (struct sockaddr *)&addr, len);   // 建立连接
    if (newsock_fd == -1)       // 调用失败返回-1
    {
        perror("connect error.\n");
        exit(1);
    }
    else 
    {
        printf("connect OK.\n");
    }
    
    len2 = sizeof(buf);
    // 参数:socket返回的套接字,发送数据的指针,数据程度,默认为0
    send(sock_fd, buf, len2, 0);
    printf("111");
    sleep(5);
    printf("222");
    // 参数:socket返回的套接字,缓冲区指针,缓冲区长度,默认0
    recv(sock_fd, rebuf, 256, 0);   // 256?
    rebuf[sizeof(rebuf) + 1] = '\0';        // 字符串末尾,手动设为0
    printf("receive message:\n%s\n.", rebuf);

    close(sock_fd);
    return 0;
}

第二版

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char * argv[])
{
    struct sockaddr_in client_socket;
    int client_fd, client_connect;
    
    /* 创建套接字结构体 */
    client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd == -1)
    {
        perror("socket error.\n");
        exit(1);
    }
    else
    {
        printf("socket successfully.\n");
    }

    client_socket.sin_family = AF_INET;
    client_socket.sin_addr.s_addr = inet_addr("10.3.119.141");
    client_socket.sin_port = htons(8080);
    bzero(&(client_socket.sin_zero), 8);

    /* 请求建立连接 */
    client_connect = connect(client_fd, (struct sockaddr *)&client_socket, sizeof(client_socket));
    if (client_connect == -1)
    {
        perror("socket error.\n");
        exit(1);
    }
    else
    {
        printf("connect successfully.\n");
    }

    /* 接受数据 */
    char buf[20]; 
    memset(buf, '0', sizeof(buf));
    recv(client_fd, buf, sizeof(buf), 0);
    printf("MSG:%s", buf);

    /* 发送数据 */
    for (int i = 0; i < 10; i++)
    {
        char str[] = "hello.\n";
        send(client_fd, str, sizeof(str), 0);
        sleep(1);
    }

    /* 关闭客户端 */
    close(client_fd);
    return 0;
}

第三版

/*
	将代码分离成函数调用的形式
*/

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
 
struct sockaddr_in initParam(void);
int initClient(struct sockaddr_in client_socket);
void dealData(int client_fd);
 
// 主函数
int main(int argc, char * argv[])
{
	// 配置参数
	struct sockaddr_in client_socket = initParam();
	// 初始化客户端
	int client_fd = initClient(client_socket);
	// 处理数据
	dealData(client_fd);
    
    /* 关闭客户端 */
    close(client_fd);
    exit(EXIT_SUCCESS);
}

// 数据处理业务
void dealData(int client_fd)
{
	char buf[20] ={0}; 
	
    /* 发送数据 */
    for (int i = 0; i < 3; i++)
    {
        char str[] = "hello.\n";
        send(client_fd, str, sizeof(str), 0);
        sleep(1);
    }
	
	/* 接受数据 */
	//memset(buf, '0', sizeof(buf));	// 不要加清零,数组最后位\0变成了0,导致数组全部打印
	recv(client_fd, buf, sizeof(buf), 0);	// 如何实现循环打印接受信息
	printf("MSG:%s", buf); 
}

// 初始化配置参数
struct sockaddr_in initParam(void)
{
	struct sockaddr_in client_socket;
    
    client_socket.sin_family = AF_INET;
    client_socket.sin_addr.s_addr = inet_addr("172.171.232.205");
    client_socket.sin_port = htons(8001);
    bzero(&(client_socket.sin_zero), 8);
	
	return client_socket;
} 

// 初始化客户端
int initClient(struct sockaddr_in client_socket)
{
	int client_fd;
	/* 创建套接字结构体 */
	client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd == -1)
    {
        perror("socket error.\n");
        exit(1);
    }
    else
    {
        printf("socket successfully.\n");
    }
	
	/* 请求建立连接 */
	int client_connect;
    client_connect = connect(client_fd, (struct sockaddr *)&client_socket, sizeof(client_socket));
    if (client_connect == -1)
    {
        perror("socket error.\n");
        exit(1);
    }
    else
    {
        printf("connect successfully.\n");
    }
	
	return client_fd;
}

第四版

/*
	在原有函数代码分离成函数调用的形式的基础之上
        增减connect重连的机制
	
*/

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>

#define MAXSLEEP 8
 
struct sockaddr_in initParam(void);
int initClient(struct sockaddr_in client_socket);
void dealData(int client_fd);
int connect_retry_2(int client_fd, struct sockaddr_in client_socket);
 
// 主函数
int main(int argc, char * argv[])
{
	// 配置参数
	struct sockaddr_in client_socket = initParam();
	// 初始化客户端
	int client_fd = initClient(client_socket);
	// 处理数据
	dealData(client_fd);
    
    /* 关闭客户端 */
    close(client_fd);
    exit(EXIT_SUCCESS);
}

// 数据处理业务
void dealData(int client_fd)
{
	char buf[20] ={0}; 
	
    /* 发送数据 */
    for (int i = 0; i < 3; i++)
    {
        char str[] = "hello.\n";
        send(client_fd, str, sizeof(str), 0);
        sleep(1);
    }
	
	/* 接受数据 */
	//memset(buf, '0', sizeof(buf));	// 不要加清零,数组最后位\0变成了0,导致数组全部打印
	recv(client_fd, buf, sizeof(buf), 0);	// 如何实现循环打印接受信息
	printf("MSG:%s", buf); 
}

// 初始化配置参数
struct sockaddr_in initParam(void)
{
	struct sockaddr_in client_socket;
    
    client_socket.sin_family = AF_INET;
    client_socket.sin_addr.s_addr = inet_addr("172.171.232.205");
    client_socket.sin_port = htons(8001);
    bzero(&(client_socket.sin_zero), 8);
	
	return client_socket;
} 

// 初始化客户端
int initClient(struct sockaddr_in client_socket)
{
	int client_fd;
	/* 创建套接字结构体 */
	client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd == -1)
    {
        perror("socket error:");
        exit(1);
    }
    else
    {
        printf("socket successfully.\n");
    }
	
	/* 请求建立连接 */
	int client_connect;
    client_connect = connect(client_fd, (struct sockaddr *)&client_socket, sizeof(client_socket));
    if (client_connect == -1)
    {
        perror("connect error:");
        //exit(1);
    }
    else
    {
        printf("connect successfully.\n");
    }
	client_fd = connect_retry_2(client_fd, client_socket);
	return client_fd;
}

// 重新连接connect retry
int connect_retry_2(int client_fd, struct sockaddr_in client_socket)
{	
	int numsec, fd;
	
	for (numsec = 1; numsec <= MAXSLEEP; numsec <<= 1)
	{
		if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		{
			return -1;
		}
		if (connect(client_fd, (struct sockaddr *)&client_socket, sizeof(client_socket)) >= 0)
		{
			return fd;
		}
		close(fd);
		if (numsec <= MAXSLEEP / 2)
		{
			printf("Connect retry\n");
			sleep(numsec);
		}
	}
	return -1;
}

// connect重连,旧的socket可能还是不行,所以要用新建的socket重新connect
int connect_retry()
{
	int numsec;
	
	for (numsec = 1; numsec <= MAXSLEEP; numsec <<= 1)
	{
		if (connect(sockfd, addr, alen) == 0)
		{
			return (0);
		}
		
		if (numsec <= MAXSLEEP / 2)
		{
			sleep(numsec);
		}
	}
	return -1;
}
posted @ 2022-04-14 21:54  starc的miao  阅读(190)  评论(0)    收藏  举报