Delphi socket连接.net Socket

[csharp] 

socket_send

(PHP 4 >= 4.1.0, PHP 5)

socket_send — Sends data to a connected socket

标准的Socket的应用程序框架如下:
Server方: Socket()[ 新建一个Socket]--Bind()[ 同服务器地址邦定
]--Listen() --Accept()--block
wait--read()[接受消息,在windows平台中,方法为send(TCP),或者是sendto(UDP)]--处理服务请求--Write()[发送消息,在windows平台中,方法为send(TCP),
或者为sendto(UDP)。
Client方相对简单:Socket()--Connect()[通过一定的port连接特定的服务器,这是与服务器建立连接]--Write()--Read()。
  Socket可以是基于TCP的,也可以是基于UDP,同时Socket甚至建立在其他的协议,比如IPX/SPX,DECNet等。在新建一个Socket时,可以指定新建何类Socket。Bind()用来同服务器的地址邦定,如果一个主机只有一个IP地址,实际上邦定的作用就相对多余了。Listen()开始监听网络,Accept()用于接受连接,其返回值是保持同客户机联系的Socket。
  在Delphi中,对于Windows中的Socket进行了有效的封装。在Delphi中,按其继承关系,可以分层两类:
一、TComponent--TAbstractSocket--TCustomSocket--TCustomServerSocket--TServerSocketTComponent--TAbstractSocket--TCustomSocket--TClientSocket二、直接从TObject继承过来:
TObject--TCustomWinSocket--TServerWinSocketTObject--TCustomWinSocket--TClientWinSocketTObject--TCustomWinSocket--TServerClientWinSocket  可以看出第一类建立在TCustomSocket基础上,第二类建立在TCustomWinSocket的基础上。第一类建立在TComponet的基础上,第二类直接构建在TObject基础上。因此如果用户非常熟悉Socket并且想要编写控制台程序时,可以使用TCustomWinScoket类。
  同uses中可以看出,它们都在ScktComp.pas中实现,而在schtComp.pas中,则包含了winsock.pas文件,如果继续深入winsock文件,在其中可以发现所有的Windows
Socket的基本方法。

转自    
自己对中间有点修改,下面是代码

Socket概念,socket

 

Socket是网络上的两个程序,通过一个双向的通信连接,实现数据的交换。这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的变成接口,一个Socket由一个IP地址和一个端口号唯一确定。

 

Socket采用TCP/IP协议模型。TCP/IP协议的传输层又有两种传输协议:TCP(传输控制协议)和UDP(用户数据报协议).TCP是基于连接的,而UDP是无连接的;TCP对系统资源的要求较多,而UDP少,TCP保证数据正确性而UDP可能丢包;TCP保证数据顺序而UDP不保证。

Socket是网络上的两个程序,通过一个双向的通信连接,实现数据的交换。这个双向链路的一端称为一个Socket.Socket通常用来…

  

Description

int socket_send ( resource socket, string buf, int len, int
flags)

 

警告

本扩展模块是实验性的。该模块的行为,包括其函数的名称以及其它任何关于此模块的文档可能会在没有通知的情况下随 PHP 以后的发布而改变。我们提醒您在使用本扩展模块的同时自担风险。

The function socket_send() sends len bytes to the socket socket
from buf

The value of flags can be any ORed combination of the following:

表格 1. possible values for flags

0x1 Process OOB (out-of-band) data
0x2 Peek at incoming message
0x4 Bypass routing, use direct interface
0x8 Data completes record
0x100 Data completes transaction

 

See also socket_sendmsg() and socket_sendto().

 

 

 <?

// set some variables
$host = “10.1.0.3”;
$port = 5038;

// don’t timeout!
set_time_limit(0);

// create socket
$commonProtocol = getprotobyname(“tcp”);
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol) or
die(“Could not create
socket/n”);
$connection=socket_connect($socket,$host,$port);
if (!$connection)
{
 echo “Can’t Connect to Asterisk Manager Port .”;
}
else
{
 echo “Connect to Asterisk Manager Successfully.”;
}

$Socket_logintext=”Action: login/r/nUsername: cron/r/nSecret:
1234/r/nEvents: ON/r/n/r/n”;
socket_send($socket,$Socket_logintext,strlen($Socket_logintext),0x4);
//socket_write($socket,$Socket_logintext,strlen($Socket_logintext));
/*
while ($buffer=socket_read($socket,1024,PHP_NORMAL_READ))
 {
 if($buffer==”NO DATA”);
 {
  echo (“<p>NO DATA</p>”);
  continue;
 }
 else
 {
  echo (“<p>Buffer Data: “.$buffer.”</p>”);
 }
}
*/
socket_close($socket);
?>

 

版权声明:本文为博主原创文章,未经博主允许不得转载。


  实际上,如果你了解了标准Socket的应用程序框架,对于使用Delphi编写Socket应用程序也就得心应手了;这不是说你必须了解复杂的Socket中的标准函数,也没有必要,因为Delphi已经为你做了很好的封装了,这也正是Delphi的强势所在,你只要了解那么一点点的基本框架。

服务端部分

这几天一直研究Delphi连接.net的socket程序,终于有一些进展。

图片 1

需求:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,ScktComp, StdCtrls, ComCtrls;

  const
    CMax=10;  //  客户端最大连接数

    // 利用此记录类型保存客户端的信息,同时保存当前客户端的连接状态
  type
    client_record=record
    CHandle:Integer;  //客户端套接字句柄
    CSocket:TCustomWinSocket;  //  客户端套接字
    CName:string;   // 客户端计算机名称
    CAddress:string;   //  客户端计算机IP地址
    CUsed:Boolean;   //客户端联机标志
  end;

type
  TForm1 = class(TForm)
    ServerSocket: TServerSocket;
    tbConnect: TButton;
    tbClose: TButton;
    tbDisconnected: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    StatusBar: TStatusBar;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Memo2: TMemo;
    lb_count: TLabel;
    procedure tbConnectClick(Sender: TObject);
    procedure tbCloseClick(Sender: TObject);
    procedure ServerSocketClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketListen(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocketClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure tbDisconnectedClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ServerSocketGetSocket(Sender: TObject; Socket: Integer;
      var ClientSocket: TServerClientWinSocket);
    procedure ServerSocketClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
  private
    { Private declarations }
  public
    { Public declarations }

    session:array[0..CMax-1] of client_record;   //  客户端连接数组

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


//  打开套接字连接,并使套接字进入监听状态
procedure TForm1.tbConnectClick(Sender: TObject);
begin
  ServerSocket.Open;
end;


//  关闭套接字连接,不再监听客户端的请求
procedure TForm1.tbCloseClick(Sender: TObject);
begin
  Close;      
end;


//  从客户端读取信息
procedure TForm1.ServerSocketClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var
    i:Integer;
begin
  //  将从客户端读取的信息添加到Memo1中
  Memo1.Lines.Add(Socket.ReceiveText);
  for i:=0 to 9 do
  begin
    //  取得匹配的客户端
    if session[i].CHandle=Socket.SocketHandle then
    begin
      session[i].CSocket.SendText('Send String To Client: '+session[i].CAddress+' ==> '+Edit1.Text);
    end;
  end;
end;

//  服务器端套接字进入监听状态,以便监听客户端的连接
procedure TForm1.ServerSocketListen(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  StatusBar.Panels[0].Text:='Waiting for Client Connect...';

end;


//  当客户端连接到服务器端以后
procedure TForm1.ServerSocketClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  i,c:Integer;
begin
  c:=0;
  for i:=0 to 9 do
  begin
    if not session[i].CUsed then
    begin
      session[i].CHandle:=Socket.SocketHandle;  // 客户端套接字句柄
      session[i].CSocket:=Socket;  // 客户端套接字
      session[i].CName:=Socket.RemoteHost;  //  客户端计算机名称
      session[i].CAddress:=Socket.RemoteAddress; //  客户端计算机IP
      session[i].CUsed:=True; // 连接数组当前位置已经占用
      Break;
    end
  end;

  StatusBar.Panels[0].Text:='Client'+Socket.RemoteHost+'Connect';

  Memo2.Lines.Clear;
  for i:=0 to 9 do
  begin
    if session[i].CUsed then
    begin
      Memo2.Lines.Add('Client Name:'+session[i].CName+'Client Address:'+session[i].CAddress);
      c:=c+1;
    end;
  end;
  lb_count.Caption:=IntToStr(c);

end;

//  当客户端断开连接时
procedure TForm1.ServerSocketClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
    i,c:Integer;
begin
  for i:=0 to 9 do
  begin
    if session[i].CHandle=Socket.SocketHandle then
    begin
      session[i].CHandle:=0;
      session[i].CUsed:=False;
      Break;
    end;
  end;
  StatusBar.Panels[0].Text:='Client'+Socket.RemoteHost+'Disconnect';

  Memo2.Lines.Clear;
  for i:=0 to 9 do
  begin
    if session[i].CUsed then
    begin
      Memo2.Lines.Add('Client Name:'+session[i].CName+'Client Address:'+session[i].CAddress);
      c:=c+1;
    end;
  end;
  lb_count.Caption:=IntToStr(c);
end;

procedure TForm1.tbDisconnectedClick(Sender: TObject);
begin
  ServerSocket.Close;
  StatusBar.Panels[0].Text:='Server Socket is Close';
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ServerSocket.Close;
end;

//  当客户端正在与服务器端连接时
procedure TForm1.ServerSocketGetSocket(Sender: TObject; Socket: Integer;
  var ClientSocket: TServerClientWinSocket);
begin
  StatusBar.Panels[0].Text:='Client is Connecting...';
end;

procedure TForm1.ServerSocketClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  StatusBar.Panels[0].Text:='Client'+Socket.RemoteHost+'Connect Error';
  ErrorCode:=0;
end;

end.

服务端截取前4个字节,转换为数字,次数字为业务代码。将决定调用哪个业务逻辑。

图片 2

[html]  

object Form1: TForm1
  Left = 420
  Top = 189
  Width = 522
  Height = 353
  Caption = 'Server'
  Color = clBtnFace
  Font.Charset = GB2312_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 200
    Top = 24
    Width = 69
    Height = 13
    Caption = 'Send to Client:'
  end
  object Label2: TLabel
    Left = 200
    Top = 48
    Width = 113
    Height = 13
    Caption = 'Receive from Client :'
  end
  object Label3: TLabel
    Left = 184
    Top = 192
    Width = 73
    Height = 13
    Caption = 'Connect Status'
  end
  object lb_count: TLabel
    Left = 296
    Top = 192
    Width = 41
    Height = 13
    Caption = 'lb_count'
  end
  object tbConnect: TButton
    Left = 16
    Top = 16
    Width = 75
    Height = 25
    Caption = 'tbConnect'
    TabOrder = 0
    OnClick = tbConnectClick
  end
  object tbClose: TButton
    Left = 16
    Top = 64
    Width = 75
    Height = 25
    Caption = 'tbClose'
    TabOrder = 1
    OnClick = tbCloseClick
  end
  object tbDisconnected: TButton
    Left = 16
    Top = 112
    Width = 97
    Height = 25
    Caption = 'tbDisconnected'
    TabOrder = 2
    OnClick = tbDisconnectedClick
  end
  object Edit1: TEdit
    Left = 280
    Top = 16
    Width = 113
    Height = 21
    TabOrder = 3
    Text = 'OK'
  end
  object Memo1: TMemo
    Left = 200
    Top = 72
    Width = 249
    Height = 105
    TabOrder = 4
  end
  object StatusBar: TStatusBar
    Left = 0
    Top = 307
    Width = 514
    Height = 19
    Panels = <
      item
        Width = 50
      end>
    SimplePanel = False
  end
  object Memo2: TMemo
    Left = 8
    Top = 208
    Width = 497
    Height = 89
    TabOrder = 6
  end
  object ServerSocket: TServerSocket
    Active = False
    Port = 1025
    ServerType = stNonBlocking
    OnListen = ServerSocketListen
    OnGetSocket = ServerSocketGetSocket
    OnClientConnect = ServerSocketClientConnect
    OnClientDisconnect = ServerSocketClientDisconnect
    OnClientRead = ServerSocketClientRead
    OnClientError = ServerSocketClientError
    Left = 112
    Top = 8
  end
end.

using System;  

客户端部分

using System.Collections.Generic;  

图片 3

using System.Text;  

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp, ComCtrls;

  const
    SocketHost='192.168.86.28';  //  服务器端地址

type
  TForm1 = class(TForm)
    tbConnected: TButton;
    tbSend: TButton;
    tbClose: TButton;
    tbDisconnected: TButton;
    ClientSocket: TClientSocket;
    Edit1: TEdit;
    Memo1: TMemo;
    StatusBar: TStatusBar;
    procedure tbConnectedClick(Sender: TObject);
    procedure tbDisconnectedClick(Sender: TObject);
    procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure tbSendClick(Sender: TObject);
    procedure tbCloseClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure ClientSocketConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocketConnecting(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocketDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//  打开套接字连接
procedure TForm1.tbConnectedClick(Sender: TObject);
begin
  ClientSocket.Open;
end;

//  关闭套接字连接
procedure TForm1.tbDisconnectedClick(Sender: TObject);
begin
  ClientSocket.Close;
end;


//  接受服务器端的回复
procedure TForm1.ClientSocketRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  Memo1.Lines.Add(Socket.ReceiveText);
end;

//  发送信息到服务器
procedure TForm1.tbSendClick(Sender: TObject);
begin
  ClientSocket.Socket.SendText(Edit1.Text);
end;

procedure TForm1.tbCloseClick(Sender: TObject);
begin
  Close;
end;


//  设置要连接的服务器端地址
procedure TForm1.FormShow(Sender: TObject);
begin
  ClientSocket.Host:=SocketHost;
end;

//  已经连接到服务器端
procedure TForm1.ClientSocketConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  tbSend.Enabled:=True;
  tbDisconnected.Enabled:=True;
  StatusBar.Panels[0].Text:='Connected'+Socket.RemoteAddress;
end;

//  正在连接到服务器端
procedure TForm1.ClientSocketConnecting(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  StatusBar.Panels[0].Text:='Connecting to server';
end;

//  当断开与服务器端的连接是发生
procedure TForm1.ClientSocketDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  tbSend.Enabled:=False;
  tbDisconnected.Enabled:=False;
  StatusBar.Panels[0].Text:='Close Connect to'+Socket.RemoteHost;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ClientSocket.Close;
end;

procedure TForm1.ClientSocketError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  StatusBar.Panels[0].Text:='Connect to server error';
  ErrorCode:=0;
end;


end.

using System.IO;  

图片 4

using System.Net.Sockets;  

object Form1: TForm1
  Left = 316
  Top = 279
  Width = 530
  Height = 325
  Caption = 'Client'
  Color = clBtnFace
  Font.Charset = GB2312_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object tbConnected: TButton
    Left = 16
    Top = 32
    Width = 75
    Height = 25
    Caption = 'tbConnected'
    TabOrder = 0
    OnClick = tbConnectedClick
  end
  object tbSend: TButton
    Left = 16
    Top = 80
    Width = 75
    Height = 25
    Caption = 'tbSend'
    TabOrder = 1
    OnClick = tbSendClick
  end
  object tbClose: TButton
    Left = 16
    Top = 128
    Width = 75
    Height = 25
    Caption = 'tbClose'
    TabOrder = 2
    OnClick = tbCloseClick
  end
  object tbDisconnected: TButton
    Left = 16
    Top = 176
    Width = 97
    Height = 25
    Caption = 'tbDisconnected'
    TabOrder = 3
    OnClick = tbDisconnectedClick
  end
  object Edit1: TEdit
    Left = 304
    Top = 16
    Width = 177
    Height = 21
    TabOrder = 4
    Text = 'Edit1'
  end
  object Memo1: TMemo
    Left = 304
    Top = 48
    Width = 185
    Height = 121
    Lines.Strings = (
      'Memo1')
    TabOrder = 5
  end
  object StatusBar: TStatusBar
    Left = 0
    Top = 279
    Width = 522
    Height = 19
    Panels = <
      item
        Width = 50
      end>
    SimplePanel = False
  end
  object ClientSocket: TClientSocket
    Active = False
    ClientType = ctNonBlocking
    Port = 1025
    OnConnecting = ClientSocketConnecting
    OnConnect = ClientSocketConnect
    OnDisconnect = ClientSocketDisconnect
    OnRead = ClientSocketRead
    OnError = ClientSocketError
    Left = 120
    Top = 32
  end
end.

using System.Threading;  

Demo下载

using PivasUpdate;  

 

using log4net;  

using System.Reflection;  

using System.Net;  

  

namespace PivasUpdate  

{  

  

    public class ServiceProcess  

    {  

        private const int LENGTH=1024;  

  

        private const int GETVERSION = 1;  

        private const int DOWNLOADNEW = 2;  

        private const int DOWNLOADFILE = 3;  

  

        public static AutoResetEvent allDone = new
AutoResetEvent(false);  

        private static readonly ILog log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);  

        private string cliendAddres;  

        private string INSTALLPATH =
ConfigUtils.GetWindowsServiceInstallPath(ConfigUtils.SERVICENAME);  

  

        public void ProcessCallback(IAsyncResult ar)  

        {  

            Socket handler = null;  

            try  

            {  

  

                StateObject state = (StateObject)ar.AsyncState;  

                handler = state.workSocket;  

                cliendAddres =
IPAddress.Parse(((IPEndPoint)handler.RemoteEndPoint).Address.ToString())

  • “:”  

                + ((IPEndPoint)handler.RemoteEndPoint).Port.ToString() +
“:”;  

  

                int bytesRead = handler.EndReceive(ar);  

                log.Info(cliendAddres + “接受到数据包大小:” + bytesRead

  • “字节”);  

  

  

                int control = BitConverter.ToInt32(state.buffer, 0);  

  

                string c = UTF8Encoding.UTF8.GetString(state.buffer, 4,
bytesRead – 4);  

  

                switch (control)  

                {  

                    case GETVERSION:  

                        log.Info(cliendAddres +
“获取最新版本,请求版本号:” + c);  

                        GetVersionNo(c, handler);  

                        break;  

                    case DOWNLOADNEW:  

                        log.Info(cliendAddres + “下载更新配置文件:” +
INSTALLPATH+”/”+c);  

                        DownLoadNew(c, handler);  

                        break;  

                    case DOWNLOADFILE:  

                        log.Info(cliendAddres + “下载文件,” +
INSTALLPATH+”/”+c);  

                        DownLoadFile(INSTALLPATH + “/” + c, handler);  

                        break;  

                    default:  

                        break;  

                }  

  

            }  

            catch (Exception e)  

            {  

                log.Error(cliendAddres + “程序出错,” + e.Message);  

            }  

            finally  

            {  

                if (handler != null)  

                {  

                    handler.Shutdown(SocketShutdown.Both);  

                    handler.Close();  

                    handler = null;  

                    log.Info(“与客户端:” + cliendAddres +
“断开连接。”);  

                }  

            }  

             

        }  

  

        public void DownLoadFile(string filePath,Socket handler)  

        {  

            if (!File.Exists(filePath))  

            {  

                string fail = “文件不存在.”;  

                log.Info(cliendAddres+”访问文件:”+filePath+”不存在。”);
 

                byte[] failBytes = Encoding.UTF8.GetBytes(fail);  

                handler.BeginSend(failBytes, 0, failBytes.Length, 0, new
AsyncCallback(SendCallBack), handler);  

                allDone.WaitOne();  

                return;  

            }  

  

            handler.BeginSendFile(filePath, new
AsyncCallback(delegate(IAsyncResult ar)  

                {  

                    handler.EndSendFile(ar);  

                    allDone.Set();  

                    log.Info(cliendAddres+”发送文件:”+filePath+”成功.”);
 

                }  

                ), handler);  

            allDone.WaitOne();  

  

  

        }  

  

  

        public void DownLoadNew(string versioncode,Socket handler)  

        {  

            string[] strs = versioncode.Split(‘.’);  

            string result = “”;  

            List<byte> resbyte = new List<byte>();  

  

            if (strs.Length != 3)  

            {  

                result = “版本号错误”;  

                log.Warn(cliendAddres+”版本号错误,” + versioncode);  

                resbyte.AddRange(Encoding.UTF8.GetBytes(result));  

                handler.BeginSend(resbyte.ToArray(), 0, resbyte.Count,
0, new AsyncCallback(SendCallBack), handler);  

                return;  

            }  

  

            FileStream stream = File.OpenRead(INSTALLPATH+”/version/” +
versioncode + “/update.xml”);  

            List<byte> list = new List<byte>();  

            int count = 0;  

  

            byte[] buf = new byte[1024];  

            while ((count=stream.Read(buf,0,buf.Length))>0)
list.AddRange(buf);  

  

            handler.BeginSendFile(INSTALLPATH+”/version/” + versioncode

  • “/update.xml”, new AsyncCallback(delegate(IAsyncResult ar)  

                {  

                    handler.EndSendFile(ar);  

                   
log.Info(cliendAddres+”发送文件成功,文件名update.xml”);  

                    allDone.Set();  

                }  

                ), handler);  

            allDone.WaitOne();  

        }  

  

        public void GetVersionNo(string content,Socket handler)  

        {  

            string[] strs = content.Split(‘.’);  

            string result = “”;  

            List<byte> resbyte = new List<byte>();  

  

            if (strs.Length != 3)  

            {  

                result = “版本号错误”;  

                log.Warn(cliendAddres+”版本号错误,”+content);  

                resbyte.AddRange(Encoding.UTF8.GetBytes(result));  

                handler.BeginSend(resbyte.ToArray(), 0, resbyte.Count,
0, new AsyncCallback(SendCallBack), handler);  

                return;  

            }  

  

            string[] dirs =
Directory.GetDirectories(INSTALLPATH+”/version”);  

            for (int i = 0; i < dirs.Length; i++)  

            {  

                if (dirs[i].EndsWith(“\\”+content))  

                {  

                    if (i != dirs.Length – 1)  

                    {  

                        result = Directory.CreateDirectory(dirs[i +
1]).Name;  

                        break;  

                    }  

                    else  

                    {  

                        result = dirs[i];  

                    }  

                }  

            }  

  

            if (result == “”)  

            {  

               
resbyte.AddRange(Encoding.UTF8.GetBytes(“没有找到此版本。”));  

                log.Warn(cliendAddres+”没有找到版本:”+content);  

            }  

            else  

            {  

                resbyte.AddRange(Encoding.UTF8.GetBytes(result));  

                log.Info(cliendAddres+”发送新版本号:”+result);  

            }  

            handler.BeginSend(resbyte.ToArray(), 0, resbyte.Count, 0,
new AsyncCallback(SendCallBack), handler);  

            allDone.WaitOne();  

        }  

  

  

        private void SendCallBack(IAsyncResult ar)  

        {  

            try  

            {  

                // Retrieve the socket from the state object.  

                Socket handler = (Socket)ar.AsyncState;  

  

                // Complete sending the data to the remote device.  

                int bytesSent = handler.EndSend(ar);  

               
log.Info(cliendAddres+”发送成功,发送字节数:”+bytesSent);  

                allDone.Set();  

  

            }  

            catch (Exception e)  

            {  

                log.Error(cliendAddres+”发送失败:”+e.Message,e);  

            }  

        }  

  

         

    }  

}  

 

以上代码为服务端逻辑。

 

delphi使用TclientSocket连接服务端程序。

 

其中有几大问题。

TclientSocket.sendBuf可以发送任意字符字节等数据,但是我们这块的想法是前4个字节为数字,后面为自定义的字符串,因此这就需要将字节进行处理。

首先将数字转换为4个字节数组,然后将字符串转换为utf8编码的字节数组然后进行组合,发送。意想不到的是程序发送成功后,没有任何返回的结果。

然后在服务端进行代码的跟踪,发现服务端接受的字节数组顺序已乱,转换的数字已经出错。因此不会返回任何的结果。

 

后来经过多方面原因的查找,发现在delphi中字节数组使用的是动态数组 array
of byte
,delphi动态数组在经过socket缓冲区时,会出现数据混乱的现象,那如何解决呢?

经多面证实发现,使用静态数组 array [1..5] of byte
可以发送成功,服务端也可以解码成功。

 

但是如果数据是动态的,长度也不确定,那么这种方式也是不适用的。所以程序还是需要改进的,可以这么做所有的指令还有数据都是字符串,服务端首先解码,转换为字符串,然后在解析字符串的指令。

经过研究sendBuf的方法发现第一个参数需要的是一个指针类型,而我传递的是一个数组,按道理来说两个的效果都是一样的,都是数组的第一个元素的地址,但是情况明显不是这样的。直接将数组当作参数返回的数数组对象的地址,而将第一个数组元素作为参数传递,则会将第一个元素的地址传递。因此将参数换掉就ok。

 

下面看一下delphi使用静态数组如何发送指令

[delphi]  

var  

 arr2 : TBytes;  

 arr1 : array [0..14] of byte;  

 seendText : UTF8String;  

 rectext : WideString;  

begin  

  mmo.Lines.Add(‘发送指令’+inttostr(1));  

  with client do  

  begin  

    Open;  

    //SetLength(arr1,4);  

    arr1[0]:=1;  

    seendText:= UTF8Encode(‘1.1302.1714’);  

    //SetLength(arr1,Length(arr1)+Length(seendText));  

    Move(seendText[1],arr1[4],Length(seendText));  

    client.Socket.SendBuf(arr1,Length(arr1));  

    rectext:=UTF8Decode(client.Socket.ReceiveText);  

    mmo.Lines.Add(rectext);  

    Close;  

  end;  

end;  

 

]
这几天一直研究Delphi连接.net的socket程序,终于有一些进展。 需求:
服务端截取前4个字节,转换为数字,次数字为业务代码。将决定…

相关文章