socket 实例实现简单通信

      学习socket 编程首先得了解一下计算机网络,谢希仁的《计算机网络》写的还是不错的,通俗易懂,作者时不时的自问自答一些小问题真心的不错,有时感觉作者在与你对话,很值得初学者看

     另外还有两篇博客写的也是不错的,很基础,链接:一个是http://www.blogjava.net/wxb_nudt/archive/2007/11/01/157623.html

   另一个是http://www.cppblog.com/lf426/archive/2008/07/08/55641.html,这个博客是一个系列的,例子生动,很到位的解释

    下边是我用C++写的基于TCP协议的socket 程序,你们可以先在自己的编译器上运行一下看一下效果,这样可以增加学习的动力

    效果图:

    服务端

  

客户端


具体操作:

 用你的编译器(VC++6.0或者VS2008、2010)打开两次,也就是两个界面,一个作为客户端一个作为服务端,在同一个机子上进行通信,用同一个IP地址。分别将下边的两个程序粘贴到你的编辑区,将ip改为你自己机子上的ip,然后运行(注意先运行服务端的)

----------------------------------------------服务端----------------------------------------

#include "winsock2.h"  //VC自带,不用下载
#include <iostream>
#pragma   comment(lib,"WS2_32.LIB")   //这一句可以避免代码移植的时候设置项目的库连接的麻烦


using namespace std;
class mserver

{
private:
      SOCKET ssock,csock;//定义一个自身的socket 也就是服务端的socket ,和一个客户端的socket ,ssock用于监听,csock用于通讯
      sockaddr_in saddr,caddr; //用来存放服务端地址和客户端地址
      int len;    //存放地址结构体的长度
      char buf[1024];  //发送的信息
public:
      mserver(); 
 mserver(int port);        //用来指定通信的地址、创建socket 环境、绑定地址和端口号
      
      void beginlisten();       //准备侦听
      void maccept();       //确认连接
      int receive();      //接收信息
 void close();    //关闭socket 
};


mserver::mserver(int port)
{
   saddr.sin_family=AF_INET;     //目前为止只用设为这一个,表示的是连接Internet,在此以前还有个针对UNIX的
   saddr.sin_port=htons(port);        //指定端口号
   saddr.sin_addr.s_addr=htonl(INADDR_ANY);       //对于多ip的机器,不论客户端发送哪个ip都能接收的到的,当然也可以针对专门的ip

                                       //注意这边的htonl,是将地址转换为网络字节序,和上边的htons 是有区别的,一个是转换short 型的一个是转换long 型的,用错会导致数据的丢失
   ssock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);         //创建socket
          
   if(ssock==SOCKET_ERROR)
{
      cout<<"socket建立失败"<<endl;
     }
   if(bind(ssock,(struct sockaddr*)&saddr,sizeof(saddr))==SOCKET_ERROR)     //绑定服务器地址,必须进行绑定,而客户端就不需要,客户端由系统自动分配
{
        cout<<"socket绑定失败"<<endl;
     }         
    len=sizeof(caddr);
}


void mserver::beginlisten()
{
     if(listen(ssock,10)==SOCKET_ERROR)
  {
            cout<<"侦听失败";
       }
}
void mserver::maccept()
{
   csock=accept(ssock,(struct sockaddr*)&caddr,&len);       //当收到客户端的连接请求后,开始接收并创建面向客户端的socket ,accept 函数的返回值是SOCKET 型,即int 型
   if(csock==INVALID_SOCKET)
   {
       cout<<"接收失败:"<<WSAGetLastError(); 
    }
       cout<<"与来自"<<inet_ntoa(caddr.sin_addr)<<"建立的连接"<<endl;
 }
int mserver::receive()
{
   memset(buf,0,1024);
   if(recv(csock,buf,1024,0)==SOCKET_ERROR)
   {
      return 0;
    }
    cout<<"客户端信息:"<<buf<<endl;
char buf1[1024];
cin.getline(buf1,1024);
    send(csock,buf1,1024,0);
    return 1;
}
void mserver::close()
 {
          closesocket(ssock);
          closesocket(csock);
  }
int main()
{
      WSADATA wsaData;
      if (WSAStartup(MAKEWORD(2,1),&wsaData))
 {
           cout<<"Winsock 初始化失败"<<endl;
           WSACleanup();
           return 0;
      }
      mserver sev(12345);
      sev.beginlisten();
      sev.maccept();
      while(sev.receive());
      sev.close();
      WSACleanup();
      return 0;
}



-----------------------------------------------------客户端-------------------------------------------

#include "winsock2.h"
#include <iostream>
#pragma   comment(lib,"WS2_32.LIB")

using namespace std;
class mclient{
private:
      SOCKET sock;
      sockaddr_in saddr;
      int len;
      char buf[1024];
public:
      mclient()
 {
          sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
          len=sizeof(saddr);
      }
      bool mconnect(char* addr,int port);
      void close();
      void msend(char* mes);//send函数只能针对面向连接的
      bool receive();
};

bool mclient::mconnect(char* addr,int port)
{
  saddr.sin_family=AF_INET;
  saddr.sin_port=htons(port); 
  saddr.sin_addr.s_addr=inet_addr(addr);
  if(connect(sock,(struct sockaddr*)&saddr,len)==SOCKET_ERROR)
  {
     cout<<"连接失败:" <<WSAGetLastError();
     return false;
   }
     return true;
}
void mclient::close()
{
  closesocket(sock);
 }
void mclient::msend(char* mes)    //向服务端发送消息
{
  send(sock,mes,strlen(mes),0);
}
bool mclient::receive()   
{
  memset(buf,0,1024);
  if(recv(sock,buf,1024,0)==SOCKET_ERROR)  //接收来自服务端的信息
  {
     return false;
  }      //recv函数对连接的和非连接的都可以使用
  else
  {
    cout<<"服务端的回应:"<<buf<<endl;
    return true;
   }
 }


int main()
{
      char buf1[1024];
 WSADATA wsaData;
      if (WSAStartup(MAKEWORD(2,1),&wsaData))
 {
           cout<<"Winsock初始化失败"<<endl;
           WSACleanup();
           return 0;
      }
      mclient person;
      if(!person.mconnect("192.168.233.1",12345))
 {
          return 0;
      }
 
      while(cin.getline(buf1,1024))
 {
          if(strcmp(buf1,"back")==0)
 {
              break;
          }
          person.msend(buf1);
          person.receive();


      }
      person.close();
      WSACleanup();//退出socket环境
      return 0;
}



代码的讲解已经写到注释里了,有些函数不了解的可以到我上边给的博客上查阅,毕竟这里涉及的函数不多

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值