当前位置:   article > 正文

TCP、UDP通信例程(C语言)_c语言在通信工程中的应用程序案例

c语言在通信工程中的应用程序案例

(转载)【socket笔记】TCP、UDP通信总结

1. 基于TCP的本地客户端、服务端信息交互实例(windows)(已验证)

实现功能:
本地TCP客户端往本地TCP服务端发送数据,TCP服务端收到数据则会打印输出,同时把原数据返回给TCP客户端。这个例子类似于我们在做单片机的串口实验时,串口上位机往我们的单片机发送数据,单片机收到数据则把该数据原样返回给上位机。

(1)服务端程序tcp_server.c

#include <stdio.h>
#include <winsock2.h>

#define BUF_LEN  100

int main(void)
{
	WSADATA wd;
	SOCKET ServerSock, ClientSock;
	char Buf[BUF_LEN] = {0};
	SOCKADDR ClientAddr;
	SOCKADDR_IN ServerSockAddr;
	int addr_size = 0, recv_len = 0;
	
	/* 初始化操作sock需要的DLL */
	WSAStartup(MAKEWORD(2,2),&wd);  
	
	/* 创建服务端socket */
	if (-1 == (ServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
	{
		printf("socket error!\n");
		exit(1);
	}
	
	/* 设置服务端信息 */
    memset(&ServerSockAddr, 0, sizeof(ServerSockAddr)); 	// 给结构体ServerSockAddr清零
    ServerSockAddr.sin_family = AF_INET;  					// 使用IPv4地址
    ServerSockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");// 本机IP地址
    ServerSockAddr.sin_port = htons(1314);  				// 端口
	
	/* 绑定套接字 */
    if (-1 == bind(ServerSock, (SOCKADDR*)&ServerSockAddr, sizeof(SOCKADDR)))
	{
		printf("bind error!\n");
		exit(1);
	}
		
	/* 进入监听状态 */
	if (-1 == listen(ServerSock, 10))
	{
		printf("listen error!\n");
		exit(1);
	}
	
	addr_size = sizeof(SOCKADDR);

	while (1)
	{
		/* 监听客户端请求,accept函数返回一个新的套接字,发送和接收都是用这个套接字 */
		if (-1 == (ClientSock = accept(ServerSock, (SOCKADDR*)&ClientAddr, &addr_size)))
		{
			printf("socket error!\n");
			exit(1);
		}

		/* 接受客户端的返回数据 */
		int recv_len = recv(ClientSock, Buf, BUF_LEN, 0);
		printf("客户端发送过来的数据为:%s\n", Buf);
		
		/* 发送数据到客户端 */
		send(ClientSock, Buf, recv_len, 0);
		
		/* 关闭客户端套接字 */
		closesocket(ClientSock);
		
		/* 清空缓冲区 */
		memset(Buf, 0, BUF_LEN);  
	}

	/*如果有退出循环的条件,这里还需要清除对socket库的使用*/
	/* 关闭服务端套接字 */
	//closesocket(ServerSock);
    /* WSACleanup();*/

	return 0;
}
  • 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

---------------------------------分割线---------------------------------

(2)客户端程序tcp_client.c

#include <stdio.h>
#include <winsock2.h>

#define BUF_LEN  100

int main(void)
{
	WSADATA wd;
	SOCKET ClientSock;
	char Buf[BUF_LEN] = {0};
	SOCKADDR_IN  ServerSockAddr;
	
	/* 初始化操作sock需要的DLL */
	WSAStartup(MAKEWORD(2,2),&wd);  
	
	/* 向服务器发起请求 */
    memset(&ServerSockAddr, 0, sizeof(ServerSockAddr));  
    ServerSockAddr.sin_family = AF_INET;
    ServerSockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    ServerSockAddr.sin_port = htons(1314);
	
	while (1)
	{
		/* 创建客户端socket */
		if (-1 == (ClientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
		{
			printf("socket error!\n");
			exit(1);
		}
		if (-1 == connect(ClientSock, (SOCKADDR*)&ServerSockAddr, sizeof(SOCKADDR)))
		{
			printf("connect error!\n");
			exit(1);
		}
		printf("请输入一个字符串,发送给服务端:");
		gets(Buf);
		/* 发送数据到服务端 */
		send(ClientSock, Buf, strlen(Buf), 0);
		
		/* 接受服务端的返回数据 */
		recv(ClientSock, Buf, BUF_LEN, 0);
		printf("服务端发送过来的数据为:%s\n", Buf);
		
		memset(Buf, 0, BUF_LEN);   // 重置缓冲区
		closesocket(ClientSock);   // 关闭套接字
	}
	
	// WSACleanup();  /*如果有退出循环的条件,这里还需要清除对socket库的使用*/
	return 0;
}
  • 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

---------------------------------分割线---------------------------------

(3.1) 方法一:在 EditPlus下编译,步骤如下:

在编译器中,加参数 -lwsock32,即可!
在这里插入图片描述
成功编译,生成 exe
在这里插入图片描述

---------------------------------分割线---------------------------------

(3.2) 方法二:在 DOS 下编译,步骤如下:

a)win+R进入dos

b)输入d:

c)输入路径  cd D:\Cplusplus\udpTest(我的文件路径)

d)先输入gcc tcp_client.c -o tcp_client.exe -lwsock32

e)再输入gcc tcp_server.c -o tcp_server.exe -lwsock32

   成功生成 exe文件!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

---------------------------------分割线---------------------------------

(5)实验步骤:

先启动服务端程序tcp_server.exe,再启动客户端程序tcp_client.exe,并在客户端中输入字符串,则当服务端会接收到字符串时会打印输出,与此同时也会往客户端返回相同的数据。
运行结果:
请添加图片描述

---------------------------------分割线---------------------------------

2. 基于UDP的本地客户端、服务端信息交互实例(待验证zhy20210913)

(1)server 程序 udp_server.c

#include <stdio.h>
#include <winsock2.h>

#define BUF_LEN  100

int main(void)
{
	WSADATA wd;
	SOCKET ServerSock;
	char Buf[BUF_LEN] = {0};
	SOCKADDR ClientAddr;
	SOCKADDR_IN ServerSockAddr;
	int addr_size = 0;
	
	
	/* 初始化操作sock需要的DLL */
	WSAStartup(MAKEWORD(2,2),&wd);  
	
	/* 创建服务端socket */
	if(-1 == (ServerSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
	{
		printf("socket error!\n");
		exit(1);
	}
	
	/* 设置服务端信息 */
    memset(&ServerSockAddr, 0, sizeof(ServerSockAddr)); 	// 给结构体ServerSockAddr清零
    ServerSockAddr.sin_family = AF_INET;  					// 使用IPv4地址
    ServerSockAddr.sin_addr.s_addr = htonl(INADDR_ANY); 	// 自动获取IP地址
    ServerSockAddr.sin_port = htons(1314);  				// 端口
	
	/* 绑定套接字 */
	
    if (-1 == (bind(ServerSock, (SOCKADDR*)&ServerSockAddr, sizeof(SOCKADDR))))
	{
		printf("bind error!\n");
		exit(1);
	}
		
	addr_size = sizeof(SOCKADDR);

	while (1)
	{
		/* 接受客户端的返回数据 */
		int str_len = recvfrom(ServerSock, Buf, BUF_LEN, 0, &ClientAddr, &addr_size);
		
		printf("客户端发送过来的数据为:%s\n", Buf);
		
		/* 发送数据到客户端 */
		sendto(ServerSock, Buf, str_len, 0, &ClientAddr, addr_size);
		
		/* 清空缓冲区 */
		memset(Buf, 0, BUF_LEN);  
	}

	/*如果有退出循环的条件,这里还需要清除对socket库的使用*/
	/* 关闭服务端套接字 */
	//closesocket(ServerSock);
    /* WSACleanup();*/

	return 0;
}
  • 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

---------------------------------分割线---------------------------------

(2)client 程序 udp_client.c

#include <stdio.h>
#include <winsock2.h>

#define BUF_LEN  100

int main(void)
{
	WSADATA wd;
	SOCKET ClientSock;
	char Buf[BUF_LEN] = {0};
	SOCKADDR ServerAddr;
	SOCKADDR_IN  ServerSockAddr;
	int ServerAddrLen = 0;
	
	/* 初始化操作sock需要的DLL */
	WSAStartup(MAKEWORD(2,2),&wd);  
	
	/* 创建客户端socket */
	if (-1 == (ClientSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
	{
		printf("socket error!\n");
		exit(1);
	}
	
	/* 向服务器发起请求 */
    memset(&ServerSockAddr, 0, sizeof(ServerSockAddr));  
    ServerSockAddr.sin_family = PF_INET;
    ServerSockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    ServerSockAddr.sin_port = htons(1314);
	
	ServerAddrLen = sizeof(ServerAddr);
	
	while (1)
	{
		printf("请输入一个字符串,发送给服务端:");
		gets(Buf);
		/* 发送数据到服务端 */
		sendto(ClientSock, Buf, strlen(Buf), 0, (struct sockaddr*)&ServerSockAddr, sizeof(ServerSockAddr));
		
		/* 接受服务端的返回数据 */
		recvfrom(ClientSock, Buf, BUF_LEN, 0, &ServerAddr, &ServerAddrLen);
		printf("服务端发送过来的数据为:%s\n", Buf);
		
		memset(Buf, 0, BUF_LEN);   // 重置缓冲区
	}
	
	closesocket(ClientSock);   // 关闭套接字
	// WSACleanup();  /*如果有退出循环的条件,这里还需要清除对socket库的使用*/
	return 0;
}

  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/144035
推荐阅读
相关标签
  

闽ICP备14008679号