基于WinSocket的单线程Client的实现

基于 WinSocket 的单线程 Client 的实现
 
功能描述:
      建立与 Socket 服务器之间的连接,向服务器端发送数据,并接收来自服务器端的数据。分别以 C++ Pascal 语言实现。并利用 Winsock 实现不同编程语言之间的通讯。
调用顺序:
l         WSAStartup 开始对WS2_32.dll的使用
l         socket 创建一个socket。
l         connect :连接至服务器。
l         send 向指定socket发送数据。
l         recv 从指定的socket接收数据。
l         WSACleanup 关闭对WS2_32.dll的使用。
函数说明:
以上函数大部分说明可以参考《基于 WinSocket 的单线程 Server 的实现 》。
  1. int connect(
  2.  SOCKET s,
  3.  const struct sockaddr* s,
  4.  const struct sockaddr* name,
  5.  int namelen
  6. );

功能:建立指定 socket 的连接。
  1. if (connect(m_socket,(SOCKADDR*)(&ClientService),sizeof(ClientService)) ==SOCKET_ERROR) {
  2.          cout << "Error on connect" << endl;
  3.          WSACleanup();
  4.          return 1;
  5.      }

 
注:
1.       delphi 中对 Winsock 函数声明位于 WinSock.pas 文件中,而不是在 WinSock2.pas ,这与 C++ 中的包含文件 Winsock2.h 不同。
2.       delphi 发送 char 数据时,指定 send 的第一个参数为 szSendBuf[0]
3.       delphi 发送 string 数据时,指定 send 的第一个参数为 szSendBuf[1]
 
客户端完整代码:
  1. // zWinsockClient.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <WinSock2.h>
  5. #include <Windows.h>
  6. #include <iostream>
  7. using namespace std;
  8.  
  9.  
  10. int _tmain(int argc, _TCHAR* argv[])
  11. {
  12.      //Initialize Winsock
  13.      WSAData wsaData;
  14.      int iResult = WSAStartup(MAKEWORD(2,2),&wsaData);
  15.      if (iResult != NO_ERROR) {
  16.          cout << "Error on WSAStartup " <<endl;
  17.          return 1;
  18.      }
  19.      //Creating a socket
  20.      SOCKET m_socket;
  21.      m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
  22.      if (m_socket == INVALID_SOCKET) {
  23.          cout << "Error on socket " << WSAGetLastError() << endl;
  24.          return 1;
  25.      }
  26.      sockaddr_in ClientService;
  27.      ClientService.sin_family = AF_INET;
  28.      ClientService.sin_addr.s_addr = inet_addr("127.0.0.1");
  29.      ClientService.sin_port = htons(27002);
  30.  
  31.      if (connect(m_socket,(SOCKADDR*)(&ClientService),sizeof(ClientService)) ==SOCKET_ERROR) {
  32.          cout << "Error on connect" << endl;
  33.          WSACleanup();
  34.          return 1;
  35.      }
  36.      //Send & receive data
  37.      int nSendBytes;
  38.      int nRecvBytes = SOCKET_ERROR;
  39.      char pSendBuf[32] = "Client:Send data";
  40.      char pRecvBuf[32] = "";
  41.      nSendBytes = send(m_socket,pSendBuf,strlen(pSendBuf),0);
  42.      cout << "Num of Send data: " << nSendBytes << endl;
  43.     
  44.      /*while (nRecvBytes == 0 ||
  45.          (nRecvBytes == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))*/ {
  46.      Sleep(5000);      
  47.      nRecvBytes = recv(m_socket,pRecvBuf,32,0);
  48.               if (nRecvBytes == -1) {
  49.                    cout << "Connection Close" << endl;
  50.                    //break;
  51.               }
  52.               if (nRecvBytes < 0) {
  53.                    return 1;
  54.               }
  55.               cout << "Num of Recv data: " << nRecvBytes << endl;
  56.               cout << pRecvBuf << endl;
  57.      }
  58.          WSACleanup();
  59.  
  60.  
  61.      return 0;
  62. }

 
delphi 实现的 Winsock 客户端代码
声明部分
 
  1. zWsaData : TWSAData; //WSADATA数据结构
  2.  zSocket : TSOCKET; //定义Socket
  3.  zClientService: sockaddr_in; //定义地址信息
  4.  
  5. procedure CheckRc(str : PChar);
实现代码
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. var
  3.            nSendBytes : Integer; //Num of send data
  4.         nRecvBytes : Integer; //Num of receive data
  5.         szSendBuf : PChar;     //char Data to send
  6.         strSendBuf: string;    //string data to send
  7.         szRecvBuf : array[0..260of Char; //buf to receive data
  8.         nRc : Integer;         //Reture code of WSA_fucntion
  9. begin
  10.        //启动WS2_32.dll
  11.        nRc := WSAStartup(MakeWord(2,2),zWSAData);
  12.         CheckRc('WSAStartup');
  13.         //创建一个Socket
  14.        zSocket := socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
  15.         if zSocket = INVALID_SOCKET then
  16.         begin
  17.                CheckRc('socket');
  18.         end;
  19.  
  20.         //连接至C服务器程序
  21.         zClientService.sin_family := AF_INET;
  22.         zClientService.sin_addr.S_addr := inet_addr('127.0.0.1');
  23.         zClientService.sin_port := htons(27002);
  24.         nRc := connect(zSocket,zClientService,SizeOf(zClientService));
  25.         if nRc = SOCKET_ERROR then
  26.         begin
  27.                CheckRc('connect');
  28.                 WSACleanup();
  29.         end;
  30.  
  31.         //send & receive data
  32.         szSendBuf := 'Data from delphi Client';
  33.         strSendBuf := 'data from delphi';
  34.         //发送的数据为string类型
  35.         //nSendBytes := send(zSocket,strSendBuf[1],length(strSendBuf),0);
  36.  
  37.         //发送的数据为char
  38.         nSendBytes := send(zSocket,szSendBuf[0],length(szSendBuf),0);
  39.         self.ListBox1.Items.Add('Num of Send = ' + IntToStr(nSendBytes));
  40.  
  41.         //接收从C服务器发送的数据
  42.         nRecvBytes := recv(zSocket,szRecvBuf,260,0);
  43.         if nRecvBytes < 0 then
  44.                Exit;
  45.         if nRecvBytes = -1 then
  46.                CheckRc('recv');
  47.  
  48.         //在组件中显示接收到的信息
  49.         self.ListBox1.Items.Add('NumOfRecv = ' + IntToStr(nRecvBytes));
  50.         self.ListBox1.Items.Add(szRecvBuf);
  51.  
  52.         //Cleanup
  53.         WSACleanup();
  54.  
  55. end;

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值