网络编程课:实验1。
程序已跑通,现贴出来详细步骤:
1.打开vc6,新建一个工程。打开菜单栏栏里的File(文件) - > New(新建) - > Projects。然后选择Win32控制台应用程序。
给工程起名tcpserver,选择工程目录(默认就可以)。之后的工程设置保持默认就好。
2.然后再文件 - >新建 - >文件。选择C ++源文件。
文件名称为tcpserver的的,位置就保存到刚才创建的工程下就好。
3.然后,开始写服务器端的代码。
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include<stdio.h>
void main()
{
WSADATA wsadata;
SOCKADDR_IN ServerAddr; //Internet通信域的地址结构
SOCKET ListeningSocket; //监听套接字
SOCKET NewConnection;
SOCKADDR_IN ClientAddr;
char DataBuffer[100];
int port = 6500; //监听套接字的端口号
int Ret;
int ClientAddrLen;
memset(DataBuffer,0,100);
//1.初始化服务器网络环境,也称为注册
if((Ret = WSAStartup(MAKEWORD(2,2),&wsadata)) !=0)//MAKEWORD(2,2)指的是应用程序要使用的WinSock规范的最高版本
//WSADATA数据用来返回WinSock API实现的细节信息
{
printf("WSAStartup failed with error %d\n",Ret);
return;
}
//2.建立服务器监听套接字
if((ListeningSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == SOCKET_ERROR)
{
printf("ListeningSocket failed with error:%d\n",WSAGetLastError());
WSACleanup();
return;
}
printf("ListeningSocket has been created!\n");
//3.初始化结构地址并与监听套接字绑定
memset((char *)&ServerAddr,0,sizeof(ServerAddr));
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY代表本地IP地址
//4.绑定套接字
if(bind(ListeningSocket,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("bind failed with error %d\n",WSAGetLastError());
WSACleanup();
return;
}
//5.启动监听
if(listen(ListeningSocket,5) == SOCKET_ERROR)
{
printf("listen failed with error %d\n",WSAGetLastError());
WSACleanup();
return;
}
//6.接受客户端连接请求并建立连接套接字
while(1)
{
ClientAddrLen = sizeof(ClientAddr);
if((NewConnection = accept(ListeningSocket,(SOCKADDR *)&ClientAddr,&ClientAddrLen)) == SOCKET_ERROR)
{
printf("accept failed with error:%d",WSAGetLastError());
WSACleanup();
return;
}
recv(NewConnection,DataBuffer,sizeof(DataBuffer),0);
printf("%s",DataBuffer);
}
//服务器连接套接字接受客户端数据
//关闭连接套接字和监听套接字,释放网络资源
closesocket(NewConnection);
closesocket(ListeningSocket);
WSACleanup();
return;
}
之后,调试运行一下。
4.再打开一个VC6窗口,按照步骤1,2-再创建一个工程,只不过这次工程名变为TcpClient的的,CPP文件变为TcpClient的的。
注意:不要试图在原有的工程之上新建一个工程,因为这样会覆盖原来的工程最好是重新打开一个VC6窗口!
5.写客户机端的代码,代码如下:
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include<stdio.h>
void main(int argc,char **argv)
{
//数据结构定义
WSADATA wsadata;
SOCKET s; //套接字描述符
SOCKADDR_IN ServerAddr; //服务器地址
int Port = 6500; //端口是6500
int Ret;
//1.初始化Winsock,也称为注册。如果初始化失败,则输出失败信息
if((Ret = WSAStartup(MAKEWORD(2,2),&wsadata)) != 0)//MAKEWORD(2,2)指的是应用程序要使用的WinSock规范的最高版本
{
printf("WSAStartup failed with error %d\n",Ret);
return;
}
//2.建立连接套接字
if((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("socket failed with error %d\n",WSAGetLastError());
WSACleanup();
return;
}
//3.初始化目的端(服务器)地址结构,先进行memset()清零操作,然后初始化
memset(&ServerAddr,0,sizeof(SOCKADDR_IN));
ServerAddr.sin_family = AF_INET; //使用的通信域是AF_INET,代表Internet域
ServerAddr.sin_port = htons(Port); //目的地址的端口号是htons(Port),htons代表把
//本机顺序转化为网络顺序,用于端口号
ServerAddr.sin_addr.s_addr = inet_addr("10.108.164.43");//设置服务器Ip地址
//inet_addr()可以把点分十进制IP地址转化为无符号长整型
//inet_ntoa()相反
//提示信息:正在试图连接服务器
printf("We are trying to connect to %s:%d...\n",inet_ntoa(ServerAddr.sin_addr),htons(ServerAddr.sin_port));
//4.然后向服务器发出连接请求
if(connect(s,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("connect failed with error %d\n",WSAGetLastError());
WSACleanup();
return;
}
//提示信息:连接成功
printf("Our connection succeeded.\n");
//提示信息:我们会发送一条消息
printf("We will now try to send a hello message.\n");
//5.向服务器发送数据
if((Ret = send(s,"Hello,ServerXX\n",14,0)) == SOCKET_ERROR)
{
printf("send failed with error %d\n",WSAGetLastError());
closesocket(s);
WSACleanup();
return;
}
//提示信息:消息发送成功
printf("We have sent a %d byte(s).\n",Ret);
//提示信息:我们即将关闭连接
printf("We are closing connection\n");
//6.关闭连接套接字释放网络资源
closesocket(s);
WSACleanup();
}
调试运行一下,不出错就行。
注意:在第3点初始化这一步骤中,设置IP地址这一行中,代码要写自己本机的IP地址如果不知道自己的IP地址,打开命令管理器输入IPCONFIG就可以看到自己的IP地址了。
6.然后,先运行的tcpserver的,再运行的TcpClient的。就可以看到连接成功的信息了。
大功告成!
最后附上一张图
不过Winsock的编程,多了两个步骤,在创建套接字之前要进行注册,调用WSAStartup(),关闭套接字之后要进行注销WSACleanup()。