主要代码如下
WSAAsyncSelect(m_Srvsock, Handle, WM_SOCKETEVENT, FD_ACCEPT or FD_CLOSE);
处理Sock消息代码
procedure TMainFrm.WMSocketEvent(var M: TSocketMessage);
var
sock: TSocket;
hThread,dd :Cardinal;
s: TSocket;
AddrIn: TSockAddrIn;
iAddInLen: Integer;
sockPm: ^tSockParam;
begin
sock :=M.Socket;
iAddInLen := sizeof(TSockAddrIn);
Case M.SelectEvent of
FD_ACCEPT:
begin
if m_Count<300 then
begin
s :=accept(sock,@AddrIn,@iAddInLen);
if s<>INVALID_SOCKET then
begin
sockPm :=nil;
GetMem(sockPm,SizeOf(tSockParam));
sockPm.sock :=S;
sockPm.Hwnd :=MainFrm.Handle;
StrCopy(sockPm.IP,inet_ntoa( AddrIn.sin_addr));
hThread :=CreateThread(nil,0,@sockThread,sockPm,0,dd);
CloseHandle(hThread);
WaitForSingleObject(hMutex,INFINITE);
m_Count :=m_Count + 1;
ReleaseMutex(hMutex);
postMessage(Handle,WU_ShowCount,0,0);
end;
end;
end;
FD_CLOSE:
begin
end;
end;
线程如下。
procedure sockThread(p: Pointer);safecall;
var
s: TSocket;
sendstr: array[0..100] of char;
settimeout :Integer;
iLen: Integer;
head_buf: array[0..100] of char;
fileHead: ^Tfile_header;
buf_pos: Integer;
iFileLen,I: Integer;
sFileContent
ointer;
iCount: Integer;
FileStream: TFileStream;
sMess: string;
sockParam: ^tSockParam;
sIp: String;
Jpg: TJPEGImage;
strm: TMemoryStream;
BMP,BMP1: TBitmap;
J :integer;
p1,p2
ByteArray;
currTime: Cardinal;
begin
sockParam :=p;
s :=sockParam.sock;
sIp :=string(sockParam.IP);
strcopy(sendstr,'220 SAFESTNET');
send(s,sendstr,length('220 SAFESTNET'),0);
currTime :=GetTickCount;
while (((GetTickCount-currTime)/1000.0)<5) do
begin
iLen :=Recv(s,head_buf,sizeof(Tfile_header),0);
if (iLen<>SOCKET_ERROR) and (iLen<>0) then
Break;
end;
if (iLen=SOCKET_ERROR) or (iLen=0) or (iLen<>sizeof(Tfile_header))then
begin
sMess :=DateTimeToStr(Now)+' '+sIp+' '+'等待接收文件信息超时!';
//writeln(sMess);
PostMess(sMess,sockParam.hWnd);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
Exit; //退出线程
end;
fileHead :=@head_buf;
if String(fileHead.header)<>'FIL' then
begin
sMess :=DateTimeToStr(Now)+' '+sIp+' '+'接收数据包错误,关闭连接...';
PostMess(sMess,sockParam.hWnd);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
Exit; //退出线程
end;
//检验是否帐号正确
//if CheckPws(fileHead.sn,fileHead.password) then
if True then
begin
strCopy(sendstr,'LOGINOK');
send(s,sendstr,length('LOGINOK'),0);
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'验证成功,开始接收文件...';
PostMess(sMess,sockParam.hWnd);
end
else
begin
strCopy(sendstr,'LOGINFAIL');
send(s,sendstr,length('LOGINFAIL'),0);
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'验证失败,关闭连接...';
PostMess(sMess,sockParam.hWnd);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
Exit; //退出线程
end;
iFileLen :=fileHead.filesize;
//检查文件类型
if LowerCase(RightStr(String(fileHead.fileName),4))<>'.jpg' then
begin
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'文件不是JGP格式,不能进行传输,关闭连接...';
PostMess(sMess,sockParam.hWnd);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
Exit; //退出线程
end;
//最大传2M的文件
if iFileLen>2*1024*1024 then
begin
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'文件过大,不能进行传输,关闭连接...';
PostMess(sMess,sockParam.hWnd);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
Exit; //退出线程
end;
iCount :=0;
GetMem(sFileContent,iFileLen+1);
buf_pos :=integer(sFileContent);
while True do
begin
currTime :=GetTickCount;
while (((GetTickCount-currTime)/1000.0)<10) do
begin
iLen :=Recv(s,pointer(buf_pos+iCount)^,iFileLen-iCount,0); //iFileLen
if (iLen<>SOCKET_ERROR) and (iLen<>0) then
Break;
end;
if (iLen=SOCKET_ERROR) or (iLen=0) then
begin
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'传输文件出错,关闭连接...';
PostMess(sMess,sockParam.hWnd);
FreeMem(sFileContent,iLen+1);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
Exit; //退出线程
end;
{if (iCount+iLen)>iFileLen+1 then
begin
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'实际收到的长度大于定义的长度,关闭连接...';
PostMess(sMess);
FreeMem(sFileContent,iLen+1);
ExitThread(s);
Exit; //退出线程
end;
For I :=0 to iLen-1 do
begin
sFileContent[I+iCount] :=buf
;
end; }
iCount :=iCount+iLen;
if iCount=iFileLen then Break;
end;
if not DirectoryExists('D:/'+fileHead.sn+'/') then
CreateDir('D:/'+fileHead.sn+'/');
if fileHead.iType=0 then
begin
Try
//文件存在就删除它
if FileExists('D:/'+fileHead.sn+'/'+fileHead.fileName) then
DeleteFile('D:/'+fileHead.sn+'/'+fileHead.fileName);
FileStream :=nil;
FileStream :=TFileStream.Create('D:/'+fileHead.sn+'/'+fileHead.fileName,fmCreate );
if FileStream<>nil then
begin
FileStream.Write(sFileContent^,iFileLen);
FileStream.Free;
FileStream :=nil;
end;
Except
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'写文件出错,关闭连接...';
PostMess(sMess,sockParam.hWnd);
FreeMem(sFileContent,iLen+1);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
Exit; //退出线程
End;
FreeMem(sFileContent,iLen+1);
end
else if fileHead.iType=1 then
begin
{Try
strm :=TMemoryStream.Create;
strm.WriteBuffer(pointer(sFileContent)^,iFileLen);
strm.Position:=0;
Jpg :=TJPEGImage.Create;
Jpg.LoadFromStream(strm);
BMP :=TBitmap.Create;
BMP.Assign(Jpg);
Jpg.DIBNeeded;
BMP1 :=TBitmap.Create;
BMP1.Assign(BMP);
//垂直镜像
for J :=0 to Bmp.Height-1 do
begin
p1 :=Bmp.ScanLine[J];
P2 :=Bmp1.ScanLine[Bmp.Height-1-J];
for I :=0 to Bmp.Width-1 do
begin
p2[3*I+2] :=p1[3*I+2];
p2[3*I+1] :=p1[3*I+1];
p2[3*I] :=p1[3*I];
end;
end;
Bmp.Free;
Jpg.Assign(Bmp1); //将bmp指定给TJpegImage对象
Jpg.CompressionQuality:=10; //压缩比例
Jpg.JPEGNeeded; //转换
Jpg.Compress;
Jpg.SaveToFile('D:/'+fileHead.sn+'/'+fileHead.fileName);
BMP1.Free;
Jpg.Free;
jpg :=nil;
Except
if jpg<>nil then jpg.Free;
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'写文件出错,关闭连接...';
PostMess(sMess);
ExitThread(s);
Exit; //退出线程
end; }
end
else
begin
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'传输文件失败...';
PostMess(sMess,sockParam.hWnd);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
Exit;
end;
sMess :=DateTimeToStr(Now)+' '+sIp+' '+String(fileHead.fileName)+' '
+IntToStr(fileHead.filesize)+'Byte'+' '+'传输文件成功...';
PostMess(sMess,sockParam.hWnd);
strCopy(sendstr,'SAFESTOK');
send(s,sendstr,length('SAFESTOK'),0);
ExitThread(s,sockParam.hWnd);
FreeMem(sockParam);
end;