(转载)【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;
WSAStartup(MAKEWORD(2,2),&wd);
if (-1 == (ServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
{
printf("socket error!\n");
exit(1);
}
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);
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)
{
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);
}
return 0;
}
---------------------------------分割线---------------------------------
(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;
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)
{
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);
}
return 0;
}
---------------------------------分割线---------------------------------
(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文件!
---------------------------------分割线---------------------------------
(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;
WSAStartup(MAKEWORD(2,2),&wd);
if(-1 == (ServerSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
{
printf("socket error!\n");
exit(1);
}
memset(&ServerSockAddr, 0, sizeof(ServerSockAddr));
ServerSockAddr.sin_family = AF_INET;
ServerSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
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);
}
return 0;
}
---------------------------------分割线---------------------------------
(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;
WSAStartup(MAKEWORD(2,2),&wd);
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);
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)