C语言实现Linux下TCP Server测试工具

Linux TCP Server测试工具代码
实现了接受数据并输出文本和十六制字符串

#include <stdio.h>
#include<string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
 
#define SERVER_PORT		8081
#define SERVER_IP		"0.0.0.0"
void ByteToHexStr(const unsigned char* source, char* dest, int sourceLen); 
int listen_fd = -1;
 
void signal_handler(int arg)
{
	printf("close listen_fd(signal = %d)\n", arg);
	close(listen_fd);
	exit(0);
}
 
int main(int argc,  char *argv[])
{
        int port=80;
        printf("argc:%d\r\n",argc);
        if (argc>1)
        {
            printf("raw data:%s",argv[1]);
            port=atoi(argv[1]);
            printf("port:%d\r\n",port);
        }
	int new_fd  = -1;
	struct sockaddr_in server;
	struct sockaddr_in client;
	socklen_t saddrlen = sizeof(server);
	socklen_t caddrlen = sizeof(client);
 
	signal(SIGINT, signal_handler);
 
	memset(&server, 0, sizeof(server));
	memset(&client, 0, sizeof(client));
 
	listen_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (listen_fd < 0)
	{
		printf("socket error!\n");
		return -1;
	}
        int opt = 1;
        setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof( opt ));
 
	server.sin_family = AF_INET;
	server.sin_port = htons(port);
	server.sin_addr.s_addr = inet_addr(SERVER_IP);
 
	if (bind(listen_fd, (struct sockaddr *)&server, saddrlen) < 0)
	{
		printf("bind error!\n");
		return -1;
	}
        printf("listen:%d\r\n",port); 
	if (listen(listen_fd, 5) < 0)
	{
		printf("listen error!\n");
		return -1;
	}
 
	char rbuf[256] = {0};
        char hexStr[1024]={0};
	int read_size = 0;
	while (1)
	{
		/*
		socket()创建的套接字默认是阻塞的,所以accept()在该套接字上进行监听时,
		如果没有客户端连接请求过来,accept()函数会一直阻塞等待;换句话说,程序
		就停在accept()函数这里,不会继续往下执行,直到有新的连接请求发送过来,唤醒accept()。
		*/
		new_fd = accept(listen_fd, (struct sockaddr *)&client, &caddrlen);
		if (new_fd < 0)
		{
			perror("accept");
			return -1;
		}
 
		printf("new client connected.IP:%s,port:%u\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
		while (1)
		{
                        memset(&rbuf,0,sizeof(rbuf));
			read_size = read(new_fd, rbuf, sizeof(rbuf));
			if (read_size < 0)
			{
				printf("read error!\n");
				continue;
			}
			else if (read_size == 0)
			{
				printf("client (%d) is closed!\n", new_fd);
				close(new_fd);
				break;
			}
 
			printf("recv:%s\n", rbuf);
                        memset(&hexStr, 0, sizeof(hexStr));
                        ByteToHexStr(rbuf,hexStr,read_size);
                        printf("recv HexStr:%s\n",hexStr);
		}
	}
 
	close(listen_fd);
 
	return 0;
}
void ByteToHexStr(const unsigned char* source, char* dest, int sourceLen)
{
    short i;
    unsigned char highByte, lowByte;
 
    for (i = 0; i < sourceLen; i++)
    {
        highByte = source[i] >> 4;
        lowByte = source[i] & 0x0f;
 
        highByte += 0x30;
 
        if (highByte > 0x39)
            dest[i * 2] = highByte + 0x07;
        else
            dest[i * 2] = highByte;
 
        lowByte += 0x30;
        if (lowByte > 0x39)
            dest[i * 2 + 1] = lowByte + 0x07;
        else
            dest[i * 2 + 1] = lowByte;
    }
    return;
}

编译

# 编译
 gcc tcpserver.c -o tcpserver
# 运行
./tcpserver 8081
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux 下进行 TCP 连接时,会经常遇到 TCP 粘包的问题。TCP 粘包的原因是网络传输的数据是以数据流的形式传输的,而不是以消息的形式传输。这就意味着在接收端,可能会将多个发送端发送的消息合并成一个消息,或者将一个消息拆分成多个消息。 以下是一个 C 语言处理 TCP 粘包的简单示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #define MAXLINE 1024 int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; char sendline[MAXLINE], recvline[MAXLINE]; if (argc != 2) { printf("usage: ./client <IP address>\n"); exit(1); } if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("socket error\n"); exit(1); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(8888); if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) { printf("inet_pton error\n"); exit(1); } if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { printf("connect error\n"); exit(1); } while (fgets(sendline, MAXLINE, stdin) != NULL) { write(sockfd, sendline, strlen(sendline)); if (read(sockfd, recvline, MAXLINE) == 0) { printf("server terminated prematurely\n"); exit(1); } // 处理 TCP 粘包 int len = strlen(recvline); if (recvline[len - 1] == '\n') { recvline[len - 1] = '\0'; } printf("received: %s\n", recvline); } exit(0); } ``` 在这个示例中,我们使用了 while 循环来不断地读取用户输入,并将用户输入的数据写入到 socket 中。在读取服务器返回的数据时,我们使用了一个简单的方法来处理 TCP 粘包问题。如果接收到的数据最后一个字符是换行符,则将其替换为字符串结束符。 这只是一个简单的示例,实际上在处理 TCP 粘包时还有许多其他的方法,例如使用定长消息、使用消息长度前缀等等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秦剑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值