c++ Socket编程流程

来源:互联网 发布:黑莓转制软件原理 编辑:程序博客网 时间:2024/05/24 06:49

 最近两天在学习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;
}

 

原创粉丝点击