Socket实现通讯 两台设备之间传输信息 C++实现

Socket实现通讯 两台设备之间传输信息 C++实现,第1张

实现的编译器是 Visual Studio 2010, 之前用的2022太新,一些头文件用不了

写的过程中对数据在传输层的通讯 ACK TCP 协议都有了新的理解

服务端和客户端分开两个project:运行注意事项:
// Server.cpp : create a console application, and include the sources in the project
//
// 1. open the *.c in the Visual C++, then “rebuild all”.
// 2. click “yes” to create a project workspace.
// 3. You need to -add the library ‘ws2_32.lib’ to your project
// (Project -> Properties -> Linker -> Input -> Additional Dependencies)
// 4. recompile the source.

代码
Server:
// You need to -add the library ‘ws2_32.lib’ to your project

#include “stdafx.h”
#include
#include
#include
#include

#define DEFAULT_PORT 5019//持续监听5019端口

int main(int argc, char **argv){

char szBuff[100];//The information of the message need to transimit
int msg_len;//the length of the message
int addr_len;//the length of the address
struct sockaddr_in local, client_addr;

SOCKET sock, msg_sock;
WSADATA wsaData;

//514
if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR){
	// stderr: standard error are printed to the screen.
	fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError());
	//WSACleanup function terminates use of the Windows Sockets DLL. 
	WSACleanup();
	return -1;
}
// Fill in the address structure
local.sin_family		= AF_INET;
local.sin_addr.s_addr	= INADDR_ANY;
local.sin_port		= htons(DEFAULT_PORT);

// protocol family:AF_INET, the type of protocol:SOCK_STREAM , When it is equal to 0, choose the type equal the type of protocols 
sock = socket(AF_INET,SOCK_STREAM, 0);	//TCP socket

if (sock == INVALID_SOCKET){
	fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}

// bind: int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
// the bind () function is to bind a name to this sock 
if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR){
	fprintf(stderr, "bind() failed with error %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}

//waiting for the connections 
//listen function() is used to see whether there is a user connected done,5 is the most acceptable devices can be taken.
if (listen(sock, 5) == SOCKET_ERROR){
	fprintf(stderr, "listen() failed with error %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}

//收到连接信息,则接收消息,并返回消息
printf("Waiting for connections ........\n");
addr_len = sizeof(client_addr);
//accept function is int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); //返回连接connect_fd
//监听套接字,accept返回一个套接字,用此完成与client的通信
msg_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len);
if (msg_sock == INVALID_SOCKET){
	fprintf(stderr, "accept() failed with error %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}

printf("accepted connection from %s, port %d\n",inet_ntoa(client_addr.sin_addr),htons(client_addr.sin_port));

while(1){
//调用网络I/O进行读写 *** 作,recieve
msg_len = recv(msg_sock, szBuff, sizeof(szBuff), 0);

if (msg_len == SOCKET_ERROR){
	fprintf(stderr, "recv() failed with error %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}
//use three times closesocket() can close the connection
if (msg_len == 0){
	printf("Client closed connection\n");
	closesocket(msg_sock);
	return -1;
}

printf("Bytes Received: %d, message: %s from %s\n", msg_len, szBuff, inet_ntoa(client_addr.sin_addr));
//recv/send
msg_len = send(msg_sock, szBuff, sizeof(szBuff), 0);
if (msg_len == 0){
	printf("Client closed connection\n");
	closesocket(msg_sock);
	return -1;
}

} //end of while loop

closesocket(msg_sock);
WSACleanup();

}

Client:
#include “stdafx.h”
#include
#include
#include
#include

#define DEFAULT_PORT 5019//定义端口号,需要后期在dos 命令窗口输入方可运行

int main(int argc, char **argv){

char szBuff[100];
int msg_len;
//int addr_len;
struct sockaddr_in server_addr;
struct hostent *hp;
SOCKET connect_sock;
WSADATA wsaData;

char			*server_name = "localhost";
unsigned short	port = DEFAULT_PORT;
unsigned int	addr;

if (argc != 3){
	printf("echoscln [server name] [port number]\n");
	return -1;
}
else{
	server_name = argv[1];
	port = atoi(argv[2]);
}

if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR){
	// stderr: standard error are printed to the screen.
	fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError());
	//WSACleanup function terminates use of the Windows Sockets DLL. 
	WSACleanup();
	return -1;
}

if (isalpha(server_name[0]))
	hp = gethostbyname(server_name);
else{
	addr = inet_addr(server_name);
	hp = gethostbyaddr((char*)&addr, 4, AF_INET);
}

if (hp==NULL)
{
	fprintf(stderr, "Cannot resolve address: %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}

//copy the resolved information into the sockaddr_in structure
memset(&server_addr, 0, sizeof(server_addr));
memcpy(&(server_addr.sin_addr), hp->h_addr, hp->h_length);
server_addr.sin_family = hp->h_addrtype;
server_addr.sin_port = htons(port);


connect_sock = socket(AF_INET,SOCK_STREAM, 0);	//TCP socket


if (connect_sock == INVALID_SOCKET){
	fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}

printf("Client connecting to: %s\n", hp->h_name);

//socket 客户端描述字, the address of the socket sever, the legth of the socket address
if (connect(connect_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR){
	fprintf(stderr, "connect() failed with error %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}

//开始实现通讯功能
while(1){
printf("input character string:\n");
gets(szBuff);

msg_len = send(connect_sock, szBuff, sizeof(szBuff), 0);

if (msg_len == SOCKET_ERROR){
	fprintf(stderr, "send() failed with error %d\n", WSAGetLastError());
	WSACleanup();
	return -1;
}

if (msg_len == 0){
	printf("server closed connection\n");
	closesocket(connect_sock);
	WSACleanup();
	return -1;
}

msg_len = recv(connect_sock, szBuff, sizeof(szBuff), 0);

if (msg_len == SOCKET_ERROR){
	fprintf(stderr, "send() failed with error %d\n", WSAGetLastError());
	closesocket(connect_sock);
	WSACleanup();
	return -1;
}

if (msg_len == 0){
	printf("server closed connection\n");
	closesocket(connect_sock);
	WSACleanup();
	return -1;
}

printf("Echo from the server %s.\n", szBuff);
}//end of while loop
//FIN package, used to close the package
closesocket(connect_sock);
WSACleanup();

}

测试的时候应该用两台电脑,一台server一台client。
当时我就用了一台,运行前把exe文件拖入dos命令窗口,输入IP地址与端口号
效果如图:

看到一个dos命令窗口发的讯息 另一个窗口是能接收到的

如果学习路上的你对这个模块还有什么疑问,欢迎随时评论区留言交流,我看到都会回复

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1295076.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-10
下一篇2022-06-10

发表评论

登录后才能评论

评论列表(0条)

    保存