C、C++网络编程(双电脑串口通讯)
在阅读本文前。请确保先查看这篇文章,学习有关TCP网编与单电脑信息传输实践。
文章目录
- C、C++网络编程(双电脑串口通讯)
- 1.让两台电脑连接同一个局域网
- 2.查询IP地址
- 3.配置端口
- 4.运行程序
- 5.程序源码(C)
-
- 6.程序源码(C++)
-
本文为华中科技大学 人工智能与自动化学院 自动化1801 魏靖旻编写整理,如有任何错误请及时指正。
在第一篇的基础上,我总结并成功实现了双电脑的即时通讯方式。
其实和单电脑最大的差别只在于两个方面,一个是IPV4地址的确定,一个是Port活动端口号的绑定。在单电脑信息传输基础上,实现双电脑串口通讯其实只需要根据以下的操作 2,3 修改两个参数。
1.让两台电脑连接同一个局域网
2.查询IP地址
a.使用cmd命令提示符,在要运行server端的电脑上查询
我们注意到此时的IPv4的地址是192.168.43.181 (IPv6和IPv4地址的区别自己百度)
b.然后我们在netstat -ano活动连接中选择本机IPv4的地址对应的端口号
然后我们选择其中的任何一个端口号(:后面的部分,比如说192.168.43.181:139,这个的端口号就是139)
至于选择什么状态的PORT,为了减小偶然误差,我在ESTABLISHED、CLOSE_WAIT、TIME_WAIT都成功过,所以自己多试一些端口就出来了。
然后很神奇的是,只要你的这两个程序成功通讯了一次,之后成功率就会大大提高。然后你会发现你选择的端口号和电脑给你配置的端口号可能会不一样,个人觉得应该是电脑自动配置端口,这里影响不大。
同时也说明一下,大部分电脑都有自己的本地端口,如果仅仅在一台电脑上进行通讯则用“127.0.0.1”+任意选择的port即可轻松实现。
3.配置端口
这也是最重要的一步,对应程序源码中的:
unsigned short Port = 49911;
以及
ServerAddr.sin_addr.s_addr = inet_addr("192.168.43.53");
这两步非常重要,后面的参数根据第二部查询IP地址得到的结果进行修改。配置好一个好的端口号,才是成功的前提。
-
在C/C++程序中,我们将两个源文件配置的端口号PORT和IP_address改成上述所说对应的即可。
-
客服端(clinet.cpp)和服务器端(server.cpp)的IP地址以及端口号要保持一致。
-
在上述我的实践过程中,IPv4就是“192.168.43.181”,端口号我选择的是57618。
-
注意:重新连接新的局域网或者发现程序有问题的时候:
a.检查本机防火墙是否阻止公用网络访问
b.要重新在cmd终端输入“netstat -ano”和“ipconfig”查看最新的IPv4的地址的活动接口
c.之后不断的换IP地址对应的端口,不断地尝试(前文提到过server.cpp和client.cpp两个端要保证IP地址和端口号一致)
4.运行程序
5.程序源码©
二者同时连接了这辆AE86,你敢上吗的热点。
其中我标了注释“//根据用户实际更改”,则按照上述第二步和第三步提到的方式更改
server端
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#define BUFFSIZE 1024
int main(int argc, char**argv)
{
int Ret;
WSADATA wsaData;
SOCKET ListeningSocket;
SOCKET NewConnection;
SOCKADDR_IN ServerAddr;
SOCKADDR_IN ClientAddr;
int ClientAddrLen = sizeof(ClientAddr);
unsigned short Port = 49911;
char sendData[BUFFSIZE];
char recvData[BUFFSIZE];
if((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
printf("WSASTARTUP_ERROR: %d\n", Ret);
return 0;
}
if((ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("SOCKET_ERROR: %d\n", INVALID_SOCKET);
return 0;
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = inet_addr("192.168.43.53");
if(bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("BIND_ERROR: %d\n", SOCKET_ERROR);
return 0;
}
if(listen(ListeningSocket, 5) == SOCKET_ERROR)
{
printf("LISTEN_ERROR: %d\n", SOCKET_ERROR);
return 0;
}
printf("正在接受连接...");
if((NewConnection = accept(ListeningSocket, (SOCKADDR *)&ClientAddr, &ClientAddrLen)) == INVALID_SOCKET)
{
printf("ACCPET_ERROR: %d\n", INVALID_SOCKET);
closesocket(ListeningSocket);
return 0;
}
printf("检测到一个连接: %s 端口:%d\n", inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port));
while(1)
{
Ret = recv(NewConnection, recvData, BUFFSIZE, 0);
if(Ret > 0)
printf("小民: %s\n", recvData);
else if(Ret < 0)
printf("RECV_ERROR: %d\n", SOCKET_ERROR);
else
{
printf("对方退出程序,聊天结束!");
break;
}
printf("\n小魏:");
scanf("%s", sendData);
if(strcmp(sendData, "quit") == 0)
break;
if(send(NewConnection, sendData, BUFFSIZE, 0) == SOCKET_ERROR)
{
printf("消息发送失败!\n");
break;
}
}
shutdown(NewConnection, SD_BOTH);
closesocket(NewConnection);
closesocket(ListeningSocket);
if(WSACleanup() == SOCKET_ERROR)
{
printf("WSACLEANUP_ERROR: %d\n", WSAGetLastError());
return 0;
}
system("pause");
return 0;
}
client端
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#define BUFFSIZE 1024
int main(int argc, char**argv)
{
int Ret;
WSADATA wsaData;
SOCKET s;
SOCKADDR_IN ServerAddr;
unsigned short Port = 49911;
char sendData[BUFFSIZE];
char recvData[BUFFSIZE];
if((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
printf("WSASTARTUP_ERROR: %d\n", Ret);
return 0;
}
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("SOCKET_ERROR: %d\n", INVALID_SOCKET);
return 0;
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = inet_addr("192.168.43.53");
if((connect(s, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr))) == SOCKET_ERROR)
{
printf("CONNECT_ERROR: %d\n", SOCKET_ERROR);
closesocket(s);
return 0;
}
while(1)
{
printf("\n小民:");
scanf("%s", sendData);
if(strcmp(sendData, "quit") == 0)
break;
if(send(s, sendData, BUFFSIZE, 0) == SOCKET_ERROR)
{
printf("消息发送失败!\n");
break;
}
Ret = recv(s, recvData, BUFFSIZE, 0);
if(Ret > 0)
printf("小魏: %s\n", recvData);
else if(Ret < 0)
printf("RECV_ERROR: %d\n", SOCKET_ERROR);
else
{
printf("对方退出程序,聊天结束!");
break;
}
}
shutdown(s, SD_BOTH);
closesocket(s);
if(WSACleanup() == SOCKET_ERROR)
{
printf("WSACLEANUP_ERROR: %d\n", WSAGetLastError());
return 0;
}
system("pause");
return 0;
}
6.程序源码(C++)
其中我标了注释“//根据用户实际更改”,则按照上述第二步和第三步提到的方式更改
server端
#include<iostream>
#include<string.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define BUFFSIZE 1024
using namespace std;
class Socket
{
private:
SOCKET sock;
sockaddr_in sockAddr;
unsigned short Port;
public:
Socket();
Socket(int n,Socket servSock);
void usebind2listen();
void chat();
void close();
};
Socket::Socket()
{
this->Port=57618;
this->sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
memset(&(this->sockAddr),0,sizeof(this->sockAddr));
this->sockAddr.sin_family = PF_INET;
this->sockAddr.sin_addr.s_addr = inet_addr("192.168.43.181");
this->sockAddr.sin_port = htons(Port);
}
Socket::Socket(int n,Socket servSock)
{
this->sock=accept(servSock.sock,(SOCKADDR*)&(this->sockAddr),&n);
cout<<"检测到一个连接:"<<inet_ntoa(this->sockAddr.sin_addr)<<"端口:"<<ntohs(this->sockAddr.sin_port)<<endl;
}
void Socket::usebind2listen()
{
bind(this->sock,(SOCKADDR*)&sockAddr,sizeof(SOCKADDR));
listen(this->sock,5);
cout<<"正在接收连接...";
}
void Socket::chat()
{
int ret;
char sendData[BUFFSIZE];
char recvData[BUFFSIZE];
while(true)
{
ret=recv(this->sock,recvData,BUFFSIZE,0);
if(ret>0)
cout<<"小民:"<<recvData<<endl;
else if(ret<0)
cout<<"recv_error"<<SOCKET_ERROR<<endl;
else
{
cout<<"对方退出程序,聊天结束"<<endl;
break;
}
cout<<endl<<"小魏:";
cin>>sendData;
cin.get();
if(strcmp(sendData,"quit")==0)
{
break;
}
if(send(this->sock,sendData,BUFFSIZE,0)==SOCKET_ERROR)
{
cout<<"发送失败";
break;
}
}
shutdown(this->sock, SD_BOTH);
}
void Socket::close()
{
closesocket(this->sock);
}
int main(int argc,char**argv)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
Socket servSock;
servSock.usebind2listen();
Socket clntSock(sizeof(sockaddr_in),servSock);
clntSock.chat();
servSock.close();
clntSock.close();
WSACleanup();
system("pause");
return 0;
}
client端
#include<iostream>
#include<string.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define BUFFSIZE 1024
using namespace std;
class CSocket
{
private:
SOCKET sock;
sockaddr_in sockAddr;
unsigned short Port;
public:
CSocket();
void useconnect();
void userecieve(char *str);
void chat();
void close();
};
CSocket::CSocket()
{
this->Port=57618;
this->sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
memset(&(this->sockAddr),0,sizeof(this->sockAddr));
this->sockAddr.sin_family = PF_INET;
this->sockAddr.sin_addr.s_addr = inet_addr("192.168.43.181");
this->sockAddr.sin_port = htons(Port);
}
void CSocket::useconnect()
{
connect(sock,(SOCKADDR*)&(this->sockAddr),sizeof(SOCKADDR));
}
void CSocket::chat()
{
int ret;
char sendData[BUFFSIZE];
char recvData[BUFFSIZE];
while(true)
{
cout<<endl<<"小民:";
cin>>sendData;
cin.get();
if(strcmp(sendData,"quit")==0)
{
break;
}
if(send(this->sock,sendData,BUFFSIZE,0)==SOCKET_ERROR)
{
cout<<"发送失败";
break;
}
ret=recv(this->sock,recvData,BUFFSIZE,0);
if(ret>0)
cout<<"小魏:"<<recvData<<endl;
else if(ret<0)
cout<<"recv_error"<<SOCKET_ERROR<<endl;
else
{
cout<<"对方退出程序,聊天结束"<<endl;
break;
}
}
shutdown(this->sock, SD_BOTH);
}
void CSocket::close()
{
closesocket(this->sock);
}
int main(int argc,char**argv)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
CSocket sock;
sock.useconnect();
sock.chat();
sock.close();
WSACleanup();
system("pause");
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)