导航:首页 > 编程语言 > delphi下的sock编程

delphi下的sock编程

发布时间:2022-05-04 17:48:52

A. DELPHI上简单高效的SOCKET控件怎么选择

主要用异步通讯方式
直接api,winsock

参考之:


SOCKET控件与直接使用API相比

Windows自带的Tracert是向远程主机发送ICMP包进行追踪,但是目前很多主机关闭了ICMP答复,这个工具不太好使了~~~~~原理咱知道,正规的Trace不就是发送TTL依次递增的UDP包吗?什么网关和路由敢随意丢弃我们的UDP包而不通知我们?ICMP包你可以不理,但是UDP包~~~~~不怕黑你???

unit YRecords;

interface

uses
Windows;

const
PACKET_SIZE = 32;
MAX_PACKET_SIZE = 512;
TRACE_PORT = 34567;
LOCAL_PORT = 5555;

type
s32 = Integer;
u32 = DWORD;
u8 = Byte;
u16 = word; PU16 = ^U16;

//
//IP Packet Header
//
PIPHeader = ^YIPHeader;
YIPHeader = record
u8verlen : u8;//4bits ver, 4bits len, len*4=true length
u8tos : u8;//type of service, 3bits 优先权(现在已经被忽略), 4bits TOS, 最多只能有1bit为1
u16totallen : u16;//整个IP数据报的长度,以字节为单位。
u16id : u16;//标识主机发送的每一份数据报。
u16offset : u16;//3bits 标志,13bits片偏移
u8ttl : u8;//生存时间字段设置了数据报可以经过的最多路由器数。
u8protol : u8;//协议类型,6表示传输层是TCP协议。
u16checksum : u16;//首部检验和。
u32srcaddr : u32;//源IP地址,不是‘xxx.xxx.xxx.xxx’的形势哦
u32destaddr : u32;//目的IP地址,同上
end;

//
//ICMP Packet Header
//
PICMPHeader = ^YICMPHeader;
YICMPHeader = record
u8type : u8;
u8code : u8;
u16chksum : u16;
u16id : u16;
u16seq : u16;
end;

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, YRecords, winsock2;

type
TForm1 = class(TForm)
ListBox1: TListBox;
Edit1: TEdit;
Button1: TButton;
procere FormCreate(Sender: TObject);
procere FormClose(Sender: TObject; var Action: TCloseAction);
procere Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function DecodeIcmpReply( pbuf: PChar; var seq: s32 ): string;
var
pIpHdr : PChar;
pIcmphdr : PICMPHeader;
sip : string;
ttl : integer;
begin
pIpHdr := pbuf;
sip := inet_ntoa( TInAddr( PIPHeader(pIpHdr)^.u32srcaddr ) );
ttl := PIPHeader(pIpHdr)^.u8ttl;

Inc( pIpHdr, (PIPHeader(pIpHdr)^.u8verlen and $0F) * 4 );
pIcmpHdr := PICMPHeader(pIpHdr);

result := ;
if pIcmpHdr^.u8type = 3 then //目的不可达信息,Trace完成
seq := 0;
if pIcmpHdr^.u8type = 11 then //超时信息,正在Trace
result := Format( %4d%32s%8d, [seq, sip, ttl] );
end;

procere ErrMsg( msg: string );
begin
MessageBox( 0, PChar(msg), Ping Program Error, MB_ICONERROR );
end;

procere TForm1.FormCreate(Sender: TObject);
var
wsa : TWSAData;
begin
if WSAStartup( $0202, wsa ) <> 0 then
ErrMsg( Windows socket is not responed. );
ListBox1.Font.Name := Courier New;
ListBox1.Font.Size := 9;
end;

procere TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if WSACleanup <> 0 then
ErrMsg( Windows socket can not be closed. );
end;

procere TForm1.Button1Click(Sender: TObject);
const
SIO_RCVALL = IOC_IN or IOC_VENDOR or 1;
var
rawsock : TSocket;
pRecvBuf : PChar;
FromAdr : TSockAddr;
FromLen : s32;
fd_read : TFDSet;
timev : TTimeVal;
sReply : string;
udpsock : TSocket;
ret : s32;
DestAdr : TSockAddr;
pSendBuf : PChar;
ttl, opt : s32;
pHost : PHostEnt;
begin
//创建一个RAWSOCK接收回应ICMP包
rawsock := socket( AF_INET, SOCK_RAW, IPPROTO_ICMP );

FromAdr.sin_family := AF_INET;
FromAdr.sin_port := htons(0);
FromAdr.sin_addr.S_addr := inet_addr(192.168.1.12); //换成你的IP

//如果不bind就无法接收包了~~~因为下面还要创建一个UDPSOCK
bind( rawsock, @FromAdr, SizeOf(FromAdr) );

Opt := 1;
WSAIoctl( rawsock, SIO_RCVALL, @Opt, SizeOf(Opt), nil, 0, @ret, nil, nil );

//接收ICMP回应包的缓冲区
pRecvBuf := AllocMem( MAX_PACKET_SIZE );

//创建一个UDPSOCK发送探测包
udpsock := socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );

//要发送的UDP数据
pSendBuf := AllocMem( PACKET_SIZE );
FillChar( pSendBuf^, PACKET_SIZE, C );

FillChar( DestAdr, sizeof(DestAdr), 0 );
DestAdr.sin_family := AF_INET;
DestAdr.sin_port := htons( TRACE_PORT );
DestAdr.sin_addr.S_addr := inet_addr( PChar(Edit1.Text) );

//如果edit1.text不是IP地址,则尝试解析域名
if DestAdr.sin_addr.S_addr = INADDR_NONE then
begin
pHost := gethostbyname( PChar(Edit1.Text) );
if pHost <> nil then
begin
move( pHost^.h_addr^^, DestAdr.sin_addr, pHost^.h_length );
DestAdr.sin_family := pHost^.h_addrtype;
DestAdr.sin_port := htons( TRACE_PORT );
ListBox1.Items.Add( Edit1.Text +IP地址->+ inet_ntoa(DestAdr.sin_addr) );
end else
begin
ListBox1.Items.Add( 解析域名: + Edit1.Text + 出错。 );
closesocket( rawsock );
closesocket(udpsock);
FreeMem( pSendBuf );
FreeMem( pRecvBuf );
exit;
end;
end;

ListBox1.Items.Add( Trace route + Edit1.Text + ...... );
Listbox1.Update;

//开始Trace!!!
ttl := 1;
while True do
begin
//设置TTL,使我们发送的UDP包的TTL依次累加
setsockopt( udpsock, IPPROTO_IP, IP_TTL, @ttl, sizeof(ttl) );
//发送UDP包到HOST
sendto( udpsock, pSendBuf^, PACKET_SIZE, 0, DestAdr, sizeof(DestAdr) );

FD_ZERO( fd_read );
FD_SET( rawsock, fd_read );
timev.tv_sec := 5;
timev.tv_usec := 0;

if select( 0, @fd_read, nil, nil, @timev ) < 1 then
break;

if FD_ISSET( rawsock, fd_read ) then
begin
FillChar( pRecvBuf^, MAX_PACKET_SIZE, 0 );
FillChar( FromAdr, sizeof(FromAdr), 0 );
FromAdr.sin_family := AF_INET;
FromLen := sizeof( FromAdr );
recvfrom( rawsock, pRecvBuf^, MAX_PACKET_SIZE, 0, FromAdr, FromLen );

sReply := DecodeIcmpReply( pRecvBuf, ttl );
if sReply <> then
begin
ListBox1.ItemIndex := ListBox1.Items.Add( sReply );
Listbox1.Update;
end;
if ttl = 0 then //如果收到目标主机的相应包,DecodeIcmpReply会把ttl==0
break;
end;

Inc( ttl );
Sleep( 110 );
end; //while not bStop do

ListBox1.Items.Add( 追踪路由完成。 );
ListBox1.Items.Add( );

closesocket( rawsock );
closesocket(udpsock);
FreeMem( pSendBuf );
FreeMem( pRecvBuf );
end;

end.


------解决方案--------------------
如果压力较大
感觉标准的不如indy
indy不如api
------解决方案--------------------
upup...
------解决方案--------------------
用INDY好点,API有点复杂
------解决方案--------------------
ICS 用了都说好!
------解决方案--------------------
1000以下的连接用INDY不错,1000以上考虑自己封装完成端口。
------解决方案--------------------
所有VCL用FastMM检测都有哪个内存泄漏的提示,如果只有一个可以忽略,楼主看看源代码就知道了。
------解决方案--------------------
简单高效就是serversocket和clientsocket

B. delphi怎样用socket发送,接受record类型的数据

网络应用分为客户端和服务端两部分,而Socket类是负责处理客户端通信的java类。通过这个类可以连接到指定IP或域名的服务器上,并且可以和服务器互相发送和接受数据。在本文及后面的数篇文章中将详细讨论Socket类的使用,内容包括Socket类基础、各式各样的连接方式、get和set方法、连接过程中的超时以及关闭网络连接等。

在本文中,我们将讨论使用Socket类的基本步骤和方法。一般网络客户端程序在连接服务程序时要进行以下三步操作。

1.连接服务器

2.发送和接收数据

3.关闭网络连接

一、连接服务器

在客户端可以通过两种方式来连接服务器,一种是通过IP的方式来连接服务器,而另外一种是通过域名方式来连接服务器。

其实这两种方式从本质上来看是一种方式。在底层客户端都是通过IP来连接服务器的,但这两种方式有一定的差异,如果通过IP方式来连接服务端程序,客户端只简单地根据IP进行连接,如果通过域名来连接服务器,客户端必须通过DNS将域名解析成IP,然后再根据这个IP来进行连接。

在很多程序设计语言或开发工具中(如C/C++、Delphi)使用域名方式连接服务器时必须自己先将域名解析成IP,然后再通过IP进行连接,而在Java中已经将域名解析功能包含在了Socket类中,因此,我们只需象使用IP一样使用域名即可。

通过Socket类连接服务器程序最常用的方法就是通过Socket类的构造函数将IP或域名以及端口号作为参数传入Socket类中。Socket类的构造函数有很多重载形式,在这一节只讨论其中最常用的一种形式:public Socket(String host, int port)。从这个构造函数的定义来看,只需要将IP或域名以及端口号直接传入构造函数即可。下面的代码是一个连接服务端程序的例子程序:

package mysocket;

import java.net.*;

public class MyConnection

{

public static void main(String[] args)

{

try

{

if (args.length > 0)

{

Socket socket = new Socket(args[0], 80);

System.out.println(args[0] + "已连接成功!");

}

else

System.out.println("请指定IP或域名!");

}

catch (Exception e)

{

System.err.println("错误信息:" + e.getMessage());

}

}

}

在上面的中,通过命令行参数将IP或域名传入程序,然后通过Socket socket = new Socket(args[0], 80)连接通过命令行参数所指定的IP或域名的80端口。由于Socket类的构造函数在定义时使用了throws,因此,在调用Socket类的构造函数时,必须使用try…catch语句来捕捉错误,或者对main函数使用throws语句来抛出错误。

测试正确的IP

java mysocket.MyConnection 127.0.0.1

输出结果:127.0.0.1已经连接成功!

测试错误的IP

java mysocket.MyConnection 10.10.10.10

输出结果:错误信息:Connection timed out: connect

注:10.10.10.10是一个并不存在的IP,如果这个IP在你的网络中存在,请使用其它的不存在的IP。

测试正确的域名

java mysocket.MyConnection www.ptpress.com.cn

输出结果:www.ptpress.com.cn已经连接成功!

测试错误的域名

java mysocket.MyConnection www.ptpress1.com.cn

输出结果:错误信息:www.ptpress1.com.cn

使用Socket类连接服务器可以判断一台主机有哪些端口被打开。下面的代码是一个扫描本机有哪些端口被打开的程序。

C. 在delphi中如何用clientsocket进行实时发送。。即在数据库读取到数据就立即发送出去。。

如果是数据库中直接可以发送出去的话, 就用触发器。

如果是自己开发程序, 需要程序来发送出去的话, 就在程序中用Timer控件,
在OnTimer事件中读取数据库中A表数据, A表需要用触发器来写入数据, 可以把需要发送出去的数据在触发器中写入到A表, 那么在程序每次读取到A表数据后就通过程序来发送, 这个不难吧?

我不知道你要发送的是具体数据呢, 还是数据集, 数据集就相对比较麻烦点了, 我也没研究过这个, 不知道是否可以用Stream来操作。

D. 谁能给我一个用Delphi写SOCKS5代理服务器的例程

所谓代理服务器 就是代理网络用户去取得网络信息。形象的说,它是网络信息的中转站.

E. Delphi下的socket(如TServerSocket)为什么没有超时属性,

waitfor函数来确定一个socket的超时设置,有msgwaitformultipleobjects,
msgwaitforsingleobject,
或用winsock.select函数也可。如果是block方式一般用线程方式来操作,使用waitfor来确定是否超时,或有数据来。。。通过setsockopt可以设置socket
recv
buffer
sizesetsockopt(clientsocket1.socket.sockethandle,
SOL_SOCKET,SO_recv{这参数叫接收buffer,查一下help},
pchar(&BufSize),
SizeOf(BufSize));
具体看一下scktcomp.pas源码
查看原帖>>

F. delphi socket编程 帮忙看下

这样写其实是有点问题的,立即连接马上就发送,个人认为在将来网络上应用的话肯定会丢失发送内容,不知具体如何,到时你试过如果真的完全没有问题麻烦告诉我一声。

至于你说发送出去别人收到的都不对,估计是因为bs:array of byte;的问题!!

如果你是这样定义的话bs:array[0..3] of byte; 且不要下面的setlength那句,应该别人收到的是对的

G. 如何用delphi socket 传递自定义对象

参考代码:
(1) delphi客户端发送:

csConnect()中

tmpstr := ipcode + '|setclient|' + ip + '|' + mac + '|' + #13#10;
Socket.SendText(tmpstr);

(2)Java服务接受:

public ServerThread2(Socket s) { // serverThread的构造器
this.request = s;
// 接收receiveServer传来的套接字
try { // 初始化输入、输出流
response = new DataOutputStream(request.getOutputStream());
input = new DataInputStream(request.getInputStream());
} catch (IOException e) {
GlobaTx.LogLn(e.getMessage());
}
}

@Override
public void run() { // 线程的执行方法
String str = "";
//StringBuilder sb=new StringBuilder();

str = input.readLine();

//下边详细处理

}

(3)java服务端返回:

/**
* 发送报文到客户端
* @param response
* @param pg
* @return
*/
public static boolean writePg(DataOutputStream response, DataPg pg) {
try {
String tmp=pg.getReturnStr()+"*";
System.out.println("sender:"+tmp);
response.writeBytes(tmp);//(s)writeUTF
response.flush();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
}
}

(4)delphi客户端接收:

csRead()中

res := Socket.ReceiveText;
tmpstr := res[length(res)];
if tmpstr <> '*' then //约定的结束字符*,防止传送不完整串
begin
pgcs := pgcs + res;
Exit;
end;
res := pgcs + res;
pgcs := '';

--------------------------------------------------------------------------------------------------------------------

大文件传送:

(1)delphi发送

procere TForm1.csfileConnect(Sender: TObject; Socket: TCustomWinSocket);
var
Buf: array[1..MAX_BUF + 1] of char;
bytes, iLength, MySendLength: Integer;
res, tmpstr, Msg: string;
bufSend: pointer;
picname: string; //保存的照片名称
ipcode: string; //机器编号
timestr: string; //时间
lt: TSYSTEMTIME;
begin
res := pg;
ipcode := tools.findsegment(res, 1, '|');
GetLocalTime(lt);

picname := ipcode + '-' + inttostr(lt.wYear) +
inttostr(lt.wMonth) + inttostr(lt.wDay) + inttostr(lt.wHour)
+ inttostr(lt.wMinute) + inttostr(lt.wSecond) + '.bmp';
tools.CaptureScreen(picname);
while tools.IsFileInUse(picname) do
begin
end;
fsSend := TFileStream.Create(picname, fmOpenRead);
Socket.SendText(ipcode + '|uppic|' + picname + '|' + inttostr(fsSend.Size) + '|' + #13#10);
if fsSend.Size > 0 then
begin
while fsSend.Position < fsSend.Size do
begin
iLength := fsSend.Size;
// - fsSend.Position;
//将数据分段发送
// if iLength > MAX_BUF then
// iLength := MAX_BUF;
GetMem(bufSend, iLength);
try
//读取文件流数据
fsSend.Read(bufSend^, iLength);
//发送长度为iLength的数据
Socket.SendBuf(bufSend^, iLength);
//进度条显示
// Probar.Position := fsSend.Position;
finally
//释放内存
FreeMem(bufSend, iLength);
end;
end;
//Socket.Close();
Timer1.Enabled := True;
end;
end;

(2)java接收

public static boolean fileWriteIn(File file, DataInputStream downStream,long length) {
FileOutputStream fileWrite = null;
try {
fileWrite = new FileOutputStream(file);

byte[] buffer = new byte[size];
int len = 0;
long n = 0;
System.out.print(" >开始接受数据,写入文件 ");
while ((len = downStream.read(buffer, 0, size)) != -1) {
fileWrite.write(buffer, 0, len);
n += len;
System.out.print(".");
if ((n + size) > length) {
int lastLen = (int) (length - n);
n += lastLen;
len = downStream.read(buffer, 0, lastLen);
fileWrite.write(buffer, 0, len);
System.out.print("-");
break;
}
}

System.out.println(" >完成接受,长度为:" + n);

//接收完成==========================
return true;
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error: " + e.getMessage());
return false;
} finally {

try {
fileWrite.close();
} catch (IOException e) {

}
}
}

----------------------------------------------------------------------------

中文传送:

msg:=UTF8Decode(HttpDecode(msg)) ;
// URLdecode(msg);
showmessage(Msg);

destr = URLEncoder.encode(body, "utf-8");
System.out.println("-URL-----------"+destr+"------------");

H. delphi中使用sock或tcp/udp

可以使用Delphi自带的控件TTcpClient。
使用步骤:设置好主机地址和端口;响应连接事件,在连接事件中记录连接状态;响应读数据事件,显示收到的数据;调用连接方法;连接后按服务器要求的格式发送数据;完毕。

I. socket 编程问题~~~~~~~急~~~~~~~~~~Access violation at address

可能是系统连接数受限吧,你可以在程序中断开某一个连接,给它腾位置

J. delphi中如何实现多线程socket通信时

我再说具体些,在delphi中实现收集socket通信时,应用TserverSocket类做办事器端,个中该类的ServerType属性有两个选择,分别决定办事器端是为每个客户request生成一个线程(选stThreadBlocking)照样所有的客户request都在一个线程中处理(选stNonBlocking),当我选择stThreadBlocking用线程方法时,客户端发送信息时,办事器端不克不及激活OnClientRead事宜,而被选择非线程方法时则可以实现。

阅读全文

与delphi下的sock编程相关的资料

热点内容
grub2命令行 浏览:618
无法获取加密卡信息 浏览:774
云服务器网卡充值 浏览:509
编程就是软件 浏览:49
服务器如何添加权限 浏览:437
引用指针编程 浏览:851
手机加密日记本苹果版下载 浏览:63
命令行括号 浏览:176
java程序升级 浏览:490
排序算法之插入类 浏览:227
gcccreate命令 浏览:73
海尔监控用什么app 浏览:64
系统盘被压缩开不了机 浏览:984
linuxredis30 浏览:541
狸窝pdf转换器 浏览:696
ajax调用java后台 浏览:905
活塞式压缩机常见故障 浏览:614
break算法 浏览:731
换电池的app是什么 浏览:771
单片机ad采样快速发送电脑 浏览:22