用API写的winsock,现在出了问题,贴出源代码,大家帮我找找问题

jsfserver 2005-12-18 09:15:03
这个是我在BCB中用API写的文件传输软件,用的是异步面向连接的TCP,传送文件一切都正常,就是在传送大型文件后,服务端程序关闭会出现莫名其妙的错误,现在我把所有代码贴出来,大家一起帮我研究改进,共同学习!


服务端代码
1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
hin=HINSTANCE(GetWindowLong(Form1->Handle,GWL_HINSTANCE));
lIdeaDlgProc=MakeProcInstance((FARPROC)IdeaDlgProc,hin);
hwdlg=CreateDialog(hin,"DLC",Form1->Handle,lIdeaDlgProc);
FreeProcInstance((FARPROC)lIdeaDlgProc);
sc.sin_family=AF_INET;
sc.sin_addr.s_addr=htonl(INADDR_ANY);
sc.sin_port=htons(8080);
WSAStartup(MAKEWORD(2,2),&wsaData);
s=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
bind(s,(struct sockaddr*)& sc,sizeof(sc));
WSAAsyncSelect(s,hwdlg,WM_SOCKET,FD_ACCEPT | FD_READ | FD_CLOSE);
listen(s,5);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
closesocket(s);
WSACleanup();
}
//---------------------------------------------------------------------------













1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#define MAX_SIZE 1048576
#include <Classes.hpp>
#include <Winuser.h>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <windows.hpp>
#include <SysUtils.hpp>
#define WM_SOCKET (WM_USER + 1)
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
SOCKET s,Accept;
AnsiString Filename="1.txt";
char savebuffer[MAX_SIZE],Recvbuffer[1024],cFilesize[4];
WSADATA wsaData;
struct sockaddr_in sc;
HWND hwdlg;
HWND hInst;
HINSTANCE hin;
FARPROC lIdeaDlgProc;
int addrlen=sizeof(sc),t,SaveFlag=0,Filehandle,count=0,Recvsize;
unsigned long CopyMove=0,Filesize=0,*pFilesize,Restsize=MAX_SIZE;
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
BOOL CALLBACK IdeaDlgProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:

ShowMessage("服务器启动成功
break;
case WM_COMMAND:
switch(wParam)
{
case IDOK:
DestroyWindow(hdlg);
hwdlg=0;
break;
}
default: return false;

case WM_SOCKET:
switch(WSAGETSELECTEVENT(lParam))

{
case FD_ACCEPT:

Accept = accept(wParam,(struct sockaddr*)& sc,&addrlen);
WSAAsyncSelect(Accept,hwdlg,WM_SOCKET,FD_ACCEPT|FD_READ|FD_CLOSE);
listen(Accept,5);
break;
case FD_READ:
switch(count)
{
case 2:
if((Filesize-1024)>=0)
{
Recvsize=recv(Accept,Recvbuffer,sizeof(Recvbuffer),0);
Filesize-=Recvsize;
}
else {
Recvsize=recv(Accept,Recvbuffer,Filesize,0);
}
if((CopyMove+Recvsize)<=MAX_SIZE)
{
memcpy(savebuffer+CopyMove,Recvbuffer,Recvsize);
CopyMove+=Recvsize;SaveFlag=1;
}
else
{
FileWrite(Filehandle,savebuffer,CopyMove);
CopyMove=0;
memcpy(savebuffer+CopyMove,Recvbuffer,Recvsize);
CopyMove+=Recvsize;SaveFlag=2;
}
break;
case 1:
count=2;
recv(Accept,cFilesize,sizeof(cFilesize),0);
Filesize=*((unsigned long*)cFilesize);
break;
case 0:
count=1;
recv(Accept,Recvbuffer,sizeof(Recvbuffer),0);
strcpy(Filename.c_str(),Recvbuffer);
Filehandle=FileCreate(Filename);
break;
default: return false;
}
break;
case FD_CLOSE:
if(SaveFlag==1){FileWrite(Filehandle,savebuffer,CopyMove);}
count=0;
CopyMove=0;
ShowMessage("对方断开了");

closesocket((SOCKET)wParam);
FileClose(Filehandle);
Filehandle=0;

break;
}
break;


}
return FALSE;
}
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

...全文
614 17 打赏 收藏 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
yz20050510 2006-03-21
  • 打赏
  • 举报
回复
我也遇到过类型的问题,原因可能是你的过程中存在一些疏漏,需要补充完整才行,具体缺什么,需要你自己一点点的试
wf2091139 2006-03-21
  • 打赏
  • 举报
回复
我将你的程序复制下来编译后在局域网的2台电脑上测试,
整过过程没发现有什么错。服务端程序关闭也没与出什么错啊。
不过我不知道 传送的文件发在什么地方了。你能不能告诉我一下
wf2091139 2006-03-21
  • 打赏
  • 举报
回复
很想学这方面的,麻烦您发一个给我,学习学习。

wangfeng@strstar.com
13661023811 2006-02-24
  • 打赏
  • 举报
回复
学习!!!!

cz8961@163.com
丹朱学棋 2006-01-05
  • 打赏
  • 举报
回复
学习~!!
lige_1971@sina.com
「已注销」 2006-01-02
  • 打赏
  • 举报
回复
我的邮箱:Toyan@tom.com
「已注销」 2006-01-02
  • 打赏
  • 举报
回复
mark
jsfserver 2005-12-29
  • 打赏
  • 举报
回复
程序发给你了!注意查收!
flowercity 2005-12-27
  • 打赏
  • 举报
回复
cptang@126.com
jsfserver 2005-12-26
  • 打赏
  • 举报
回复
不是这个问题!主要是程序退出时出错的!我把这一段删了,也一样出错!你们能不能帮我找出原因啊?我可以把整个代码发给你们!
donwmufromdying 2005-12-22
  • 打赏
  • 举报
回复
case WM_COMMAND:
switch(wParam)
{
case IDOK:
DestroyWindow(hdlg);
hwdlg=0;
break;
}
default: return false;
这里面会不会有逻辑问题啊?特别是大括号和break
jsfserver 2005-12-21
  • 打赏
  • 举报
回复
程序运行期间一切正常,在运行结束后关闭程序时,才出现错误!
iec 2005-12-21
  • 打赏
  • 举报
回复
用GetLastError()看是什么错误。
sfengnet 2005-12-19
  • 打赏
  • 举报
回复
你可以用 getsockopt 来查看一下服务器端在接收大文件时的sock的状态

getsockopt(取得socket状态)
相关函数 setsockopt

表头文件 #include<sys/types.h>
#include<sys/socket.h>

定义函数 int getsockopt(int s,int level,int optname,void* optval,socklen_t* optlen);

函数说明 getsockopt()会将参数s所指定的socket状态返回。参数optname代表欲取得何种选项状态,而参数optval则指向欲保存结果的内存地址,参数optlen则为该空间的大小。参数level、optname请参考setsockopt()。

返回值 成功则返回0,若有错误则返回-1,错误原因存于errno

错误代码 EBADF 参数s 并非合法的socket处理代码
ENOTSOCK 参数s为一文件描述词,非socket
ENOPROTOOPT 参数optname指定的选项不正确
EFAULT 参数optval指针指向无法存取的内存空间

范例 #include<sys/types.h>
#include<sys/socket.h>
main()
{
int s,optval,optlen = sizeof(int);
if((s = socket(AF_INET,SOCK_STREAM,0))<0) perror(“socket”);
getsockopt(s,SOL_SOCKET,SO_TYPE,&optval,&optlen);
printf(“optval = %d\n”,optval);
close(s);}

执行 optval = 1 /*SOCK_STREAM的定义正是此值*/

jsfserver 2005-12-18
  • 打赏
  • 举报
回复
编译器错误显示:
Project Project1.exe raised exception class EInvalidPointer with message 'Invalid
pointer operation'. Process stopped.Use step or Run to continue.
jsfserver 2005-12-18
  • 打赏
  • 举报
回复
补发服务端的对话框资源代码
1.rc
DLC DIALOG -1, -1, 102, 122
STYLE WS_POPUP | WS_CAPTION | WS_VISIBLE
CAPTION "哈哈!"
{
LTEXT "OK" -1,15,17,111,13
DEFPUSHBUTTON "确定" IDOK,65,60,30,14
}
jsfserver 2005-12-18
  • 打赏
  • 举报
回复
客户端代码



2.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
sc.sin_family=AF_INET;
sc.sin_addr.s_addr=inet_addr("127.0.0.1");
sc.sin_port=htons(8080);
WSAStartup(MAKEWORD(2,2),&wsaData);
s=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(connect(s,(struct sockaddr *)&sc,sizeof(sc))==0)
{ShowMessage("连上了");
Button2->Enabled=true;
Button1->Enabled=false;}
else ShowMessage("连接失败,请检查!");



}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Button3->Enabled=false;
Button2->Enabled=false;
hand=CreateThread(NULL,
0,
ThreadFunc,
Form1,
0,
&threadID);


}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
OpenDialog1->Execute();
Label2->Caption=ProgressBar1->Position;
Label1->Caption=OpenDialog1->FileName;
if(OpenDialog1->FileName!="")
{
Button3->Enabled=true;
Button2->Enabled=false;
Button1->Enabled=false;
Label2->Caption="";
ProgressBar1->Position=0;
}
filehandle=FileOpen(OpenDialog1->FileName,fmOpenReadWrite);
strcpy(Filename,ExtractFileName(OpenDialog1->FileName).c_str());
send(s,Filename,sizeof(Filename),0);
Filesize=FileSeek(filehandle,0,2);
ShowMessage(Filesize);
pfilesize=(char *)(&Filesize);
memcpy(filesize,pfilesize,4);
send(s,filesize,sizeof(filesize),0);
FileSeek(filehandle,0,0);
Restsize=Filesize;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------

//---------------------------------------------------------------------------



//---------------------------------------------------------------------------


//---------------------------------------------------------------------------

2.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
#define MAX_SIZE 10485760
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <winsock2.h>
#include <ComCtrls.hpp>
#include <Dialogs.hpp>
#include <SysUtils.hpp>
#pragma comment(lib,"ws2_32.lib")
SOCKET s;
WSADATA wsaData;
struct sockaddr_in sc;
char Filename[1024],filebuffer[MAX_SIZE],sendbuffer[1024],*pfilesize,filesize[4];
char * pbuf;
int filehandle=0,reads=0,sends=0,error=0;
unsigned long sendedsize=0,Sendsize=0,Filesize=0,Restsize=0,Readsize=0,count=0,OKsend=0,*punlong,SendMove=0;
HANDLE hand;
DWORD threadID;
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TButton *Button3;
TProgressBar *ProgressBar1;
TLabel *Label1;
TOpenDialog *OpenDialog1;
TLabel *Label2;
TLabel *Label3;
TLabel *Label4;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);



private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
DWORD WINAPI ThreadFunc(PVOID pvParam)
{
sendedsize=0;
TForm1 *ppbar;
ppbar=(TForm1*)pvParam;

do
{
if(Restsize>=MAX_SIZE)
{
Readsize=FileRead(filehandle,filebuffer,MAX_SIZE);
Restsize-=Readsize;SendMove=0;
}
else
{
Readsize=FileRead(filehandle,filebuffer,Restsize);
Restsize-=Readsize;SendMove=0;
}
do
{
if(Readsize>=1024)
{ memcpy(sendbuffer,filebuffer+SendMove,1024);
Sendsize=send(s,sendbuffer,1024,0);
Readsize-=Sendsize;
SendMove+=Sendsize;
sendedsize+=Sendsize;
}
else if(Readsize<1024)
{
memcpy(sendbuffer,filebuffer+SendMove,Readsize);
Sendsize=send(s,sendbuffer,Readsize,0);
Readsize-=Sendsize;
sendedsize+=Sendsize;
}
else {error=1;}

ppbar->ProgressBar1->Position=(double(sendedsize)/double(Filesize))*100;
ppbar->Label2->Caption=int((double(sendedsize)/double(Filesize))*100);
}while((Readsize!=0)&&(error==0));
}while((Restsize!=0)&&(error==0));
FileClose(filehandle);
closesocket(s);
ppbar->Button1->Enabled=true;
return 1;
}
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧