最近两天在学习c++的socket编程,大致流程已经搞清楚,今天晚上用控制台模拟了下通信流程,现在拿出来和大家分享一下,如果有错误还请多多指正。
#include <iostream>
#include <string>
#include "winsock.h"
#pragma comment(lib, "wsock32")
using namespace std;
int main()
{
int ret = 0;
//服务器端口初始化
WSADATA wsadata;
WORD version = MAKEWORD(2,0);
ret = WSAStartup(version,&wsadata);
if(ret != 0)
{
cout << "Server Socket Initialized error!" << endl;
return 0;
}
else
{
cout << "Server Socket Initialized OK!" << endl;
}
cout << endl;
//服务器端口创建
SOCKET m_hServerSocket;
m_hServerSocket = socket(AF_INET,SOCK_STREAM,0);
if(INVALID_SOCKET == m_hServerSocket)
{
cout << "Server Socket Created Error!" << endl;
return 0;
}
else
{
cout << "Server Socket Created OK!" << endl;
}
cout << endl;
//服务器端口绑定
SOCKADDR_IN m_addr;
m_addr.sin_family = AF_INET;
m_addr.sin_addr.S_un.S_addr = INADDR_ANY;//如果服务器是单网卡的,则就是这块网卡的ip地址;如果是多网卡,则是其中的任意一块的ip地址
m_addr.sin_port = htons(1028);
ret = bind(m_hServerSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr));
if(SOCKET_ERROR == ret)
{
cout << "Server Socket Bind Error!" << endl;
return 0;
}
else
{
cout << "Server Socket Bind OK!" << endl;
}
cout << endl;
//服务器端口开始监听
ret = listen(m_hServerSocket,20);
if (SOCKET_ERROR == ret)
{
cout << "Server Socket Listen Error!" << endl;
return 0;
}
else
{
cout << "Server Socket Listen OK!" << endl;
}
cout << endl;
//客户端端口初始化
WSADATA cli_wsadata;
ret = WSAStartup(version,&cli_wsadata);
WSAStartup(version,&cli_wsadata);
if (ret != 0)
{
cout << "Client Socket Initialize Error!" << endl;
return 0;
}
else
{
cout << "Client Socket Initialize OK!" << endl;
}
cout << endl;
//客户端端口创建
SOCKET m_hClientSocket;
m_hClientSocket = socket(AF_INET,SOCK_STREAM,0);
if (INVALID_SOCKET == m_hClientSocket)
{
cout << "Client Socket Create Error!" << endl;
return 0;
}
else
{
cout << "Client Socket Create OK!" << endl;
}
cout << endl;
//在Windows下,Socket是以DLL的形式实现的。在DLL内部维持着一个计数器,只有第一次调用WSAStartup才真正装载DLL,
//以后的调用只是简单的增加计数器,而WSACleanup函数的功能则刚好相反,每调用一次使计数器减1,当计数器减到0时,
//DLL就从内存中被卸载!因此,你调用了多少次WSAStartup,就应相应的调用多少次的WSACleanup。
//如果应用程序调用了WSAStartup()三次,它就必须调用WSACleanup()三次.对WSACleanup()的前两次调用除了减少内置计数
//器以外不做任何事, 对任务的最后一次WSACleanup()调用为任务释放了所有所需的资源。
WSACleanup();
WSACleanup();
//客户端想服务器发送连接请求
SOCKADDR_IN m_addr1;
m_addr1.sin_family = AF_INET;
m_addr1.sin_addr.S_un.S_addr = inet_addr("192.168.100.58");//服务器的ip地址
m_addr1.sin_port = htons(1028);//服务器socket的端口号
ret = connect(m_hClientSocket,(LPSOCKADDR)&m_addr1,sizeof(m_addr1));//从客户端端口m_hClientSocket想服务器端口m_addr1发送连接请求
if (SOCKET_ERROR == ret)
{
cout << "Client Connect Error!" << endl;
return 0;
}
else
{
cout << "Client Connect OK!" << endl;
}
cout << endl;
//服务器端接受客户端请求后,开放一个真正的通信端口com_sock进行通信
//注意:服务器端必须在客户端connect请求连接之后才调用accept接受请求,否则将无限等待。
//当然,如果专门开一个线程专门用于监听则可以放在任何位置了。
SOCKET com_Sock;
com_Sock = accept(m_hServerSocket,NULL,NULL);//服务器端口m_hServerSocket使用accept接受请求,并在服务器端返回com_sock进行真正通信
//客户端向服务器发送信息
char Clisend_msg[] = "Hello Server,I'm Client";
int len_send = send(m_hClientSocket,Clisend_msg,sizeof(Clisend_msg),0);//只需向本机(客户端)发送信息即可,因为已经和服务器建立连接,
if (len_send != sizeof(Clisend_msg)) //信息如何传送不用我们关心
{
cout << "Client Send Error!" << endl;
return 0;
}
else
{
cout << "Client Send OK!" << endl;
}
////服务器端接受开放一个真正的通信端口
//SOCKET com_Sock;
//com_Sock = accept(m_hServerSocket,NULL,NULL);
//服务器从通信端口接受信息
char Serrecv_msg[100];
ret = recv(com_Sock,Serrecv_msg,100,0);//服务器接受信息时候,是从accept函数返回的实际通信端口com_sock接受信息
if (SOCKET_ERROR == ret)
{
cout << "Server Receive Error!" << endl;
return 0;
}
else
{
cout << "Server Receive OK!" << endl;
}
//recv_msg[ret] = '\0';
cout << "The Message From Client is:"<< endl;
cout << Serrecv_msg << endl;
cout << endl;
//服务器向客户端发送信息
char Sersend_msg[] = "Hello Server,I'm Server";
len_send = send(com_Sock,Sersend_msg,sizeof(Sersend_msg),0);//服务器需要向和客户端真正进行通信的那个端口发送信息,
if (len_send != sizeof(Sersend_msg)) //即accept返回的com_Sock端口至于中介信息如何传送不用我们关心
{
cout << "Server Send Error!" << endl;
return 0;
}
else
{
cout << "Server Send OK!" << endl;
}
// WSACleanup();
//客户端从服务器接受信息
char Clirecv_msg[100];
ret = recv(m_hClientSocket,Clirecv_msg,100,0);//客户端接受信息时候,是从本机和服务器连接的那个socket接受信息
if (SOCKET_ERROR == ret)
{
cout << "Client Receive Error!" << endl;
return 0;
}
else
{
cout << "Client Receive OK!" << endl;
}
//recv_msg[ret] = '\0';
cout << "The Message From Server is:"<< endl;
cout << Clirecv_msg << endl;
cout << endl;
WSACleanup();
return 0;
}