您的位置:首页 > 理论基础 > 计算机网络

某实例+修改 Winsock实现基于TCP的客户端/服务器通信

2010-11-05 11:09 901 查看
  1.实例题目:Winsock实现基于TCP的客户端/服务器通信。

  2.实例分析:确定使用编程环境为Visual C++ 6.00,采用控制台应用程序“Win32 Console Application”。本例子为实现简单TCP通信,编写基于TCP的服务器端/客户端通信代码。

  3.实例代码:

  (1)服务器端程序代码

sever.cpp

#include<Winsock2.h>
#include<stdio.h>
#include<stdlib.h>

#define PORT 5000

void main()
{
  int port=PORT;
  WSADATA wsaData;
  SOCKET sListen,sAccept;

  int iLen; //客户地址长度
  int iSend; //发送数据长度
  char buf[]="Hello,How are you!"; //需要发送信息
  struct sockaddr_in serv,cliet; //服务器、客户的地址

  if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
  {
    printf("Winsock load failed/n");
    return;
  }
  
  //创建套接字
  sListen=socket(AF_INET,SOCK_STREAM,0);
  if(sListen==INVALID_SOCKET)
  {
    printf("socket failed:%d/n",WSAGetLastError());
    return;
  }
  else
  {
    printf("socket OK!");
  }
  
  //建立服务器地址
  serv.sin_family=AF_INET;
  //把一个双字节主机字节顺序的数据转换为网络字节顺序
  serv.sin_port=htons(port);
  //把四个字节主机字节顺序转换为网络字节顺序,INADDR_ANY为系统指定的IP地址
  serv.sin_addr.s_addr=htonl(INADDR_ANY);
  if(bind(sListen,(LPSOCKADDR)&serv,sizeof(serv))==SOCKET_ERROR)
  {
    printf("bind() failed:%d/n",WSAGetLastError());
    return;
  }
  else
  {
    printf("bind() OK/n");
  }
  
  //进入监听状态
  if(listen(sListen,5)==SOCKET_ERROR)
  {
    printf("listen() failed:%d/n",WSAGetLastError());
    return;
  }
  else
  {
    printf("listen() OK/n");
  }

  iLen=sizeof(cliet); //初始化客户地址长度

  //进入循环,等待客户连接请求
  while(1)
  {
    sAccept=accept(sListen,(struct sockaddr*)&cliet,&iLen);
    if(sAccept==INVALID_SOCKET)
    {
      printf("accept() failed:%d/n",WSAGetLastError());
      break;
    }
  
    //输出已连接客户IP地址和端口
    printf("accepted client IP:[%s],port:[%d]/n",inet_ntoa(cliet.sin_addr),ntohs(cliet.sin_port));

    iSend=send(sAccept,buf,sizeof(buf),0);
    if(iSend==SOCKET_ERROR)
    {
      printf("send() failed:%d/n",WSAGetLastError());
      break;
    }
    else if(iSend==0) break;
    else
      printf("send() byte:%d/n",send);
    closesocket(sAccept);
  }
  closesocket(sListen);
  WSACleanup();
}

(2)客户端程序代码

client.cpp

#include<Winsock2.h>
#include<stdio.h>
#define PORT 5000
#define BUFFER 1024

void main(int argc,char *argv[])
{
  WSADATA wsaData;
  SOCKET client;
  int port=PORT;

  int iLen; //从服务器接受的数据长度
  char buf[BUFFER]; //接受数据的缓冲
  struct sockaddr_in serv; //服务器端地址

  //接受数据缓冲区初始化
  memset(buf,0,sizeof(buf));
  if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
  {
    printf("Winsock load failed/n");
    return;
  }

  serv.sin_family=AF_INET;
  serv.sin_port=htons(port);
  serv.sin_addr.s_addr=inet_addr(argv[1]);
  
  client=socket(AF_INET,SOCK_STREAM,0);
  if(client==INVALID_SOCKET)
  {
    printf("scoket() failed:%d/n",WSAGetLastError());
    return;
  }

  if(connect(client,(struct sockaddr*)&serv,sizeof(serv))==INVALID_SOCKET)
  {
    printf("connect() failed:%d/n",WSAGetLastError());
    return;
  }
  else
  {
    iLen=recv(client,buf,sizeof(buf),0);
    if(iLen==0) return;
    else if(iLen==SOCKET_ERROR)
    {
      printf("recv() failed:%d/n",WSAGetLastError());
      return;
    }
    printf("recv() data from server:%s/n",buf);
    closesocket(client);
    WSACleanup();

    printf("press any key to continue");
    while(1);
  }
}

  4.运行实例

  在进行编译与链接前,需要注意以下几个问题:

  (1)在Visual C++6.0的"project"-->"setting"-->"project setting"-->"link"-->"object/lib module"中加入"ws2_32.lib"。PS:两个程序都要加。

  (2)执行VC++安装目录下文件夹"bin"中的"Vcvars32.bat"文件。

  (3)如果是在同一台电脑上调试服务器和客户端程序,则需要分别为他们开启一个DOS窗口。方法:在你编译运行了程序后,会在每个程序建立目录下找到一个"Debug"文件夹,里面会有一个exe文件,分别运行client.exe和sever.exe文件就OK了。

  补充:先运行服务端程序,再运行客户端程序。运行客户端程序的时候,不能直接运行,不然会提示:connect() failed:10049 我们需要为client.exe建立快捷方式,然后右击快捷方式,"属性"-->"快捷方式",在目标后面加上空格+127.0.0.1 然后运行就OK了,下图为运行一个服务端程序与两个客户端程序的结果:

持<FIELDSET>,代码看起来很悲剧,于是只好发到这里了= =

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: