📄 connections.cpp
字号:
#include "stdafx.h"
#include "FileServer.h"
#include "FileServerDlg.h"
#include "DlgProxy.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CFileServerDlg *pDlg;
int ServerSocket = 0;
extern int Killing;
void ReportError(int id, bool fatal, int err)
{
CString msg;
if (Killing) return;
msg.LoadString(id);
if (err!=0) {
char vl[64];
itoa(err,vl,10);
msg += " - ";
msg = msg+vl;
}
::MessageBox(pDlg->m_hWnd,msg,"TCP/IP File server",MB_OK);
if (fatal) pDlg->PostMessage(WM_CLOSE,0,0);
}
void ReportError(int id, bool fatal, CString &amsg)
{
CString msg;
if (Killing) return;
msg.LoadString(id);
if (amsg.GetLength()>0) {
msg += " - ";
msg = amsg;
}
::MessageBox(pDlg->m_hWnd,msg,"TCP/IP File server",MB_OK);
if (fatal) pDlg->PostMessage(WM_CLOSE,0,0);
}
enum {
std_rdonly = 0x0000,
std_wronly = 0x0001,
std_rdwr = 0x0002,
std_append = 0x0008,
std_truncate =0x0200,
std_create = 0x0100,
std_binary = 0x8000,
std_text = 0x4000
};
void SetAccess(int flag, char *acc)
{
acc[1] = 0;
acc[2] = 0;
switch (flag&0x07) {
case std_rdonly:
acc[0] ='r';
break;
case std_wronly:
if (flag & std_append) {
acc[0] ='a';
} else {
if ((flag&std_create) || (flag&std_truncate) ) {
acc[0] = 'w';
} else {
acc[0] = 'r';
acc[1] = '+';
}
}
break;
case std_rdwr:
if (flag&std_append) {
acc[0] = 'a';
acc[1] = '+';
} else {
if (flag&std_create) {
acc[0] = 'w';
} else {
acc[0] = 'r';
}
acc[1] = '+';
}
break;
default:
acc[0]=0;
break;
}
if (flag&std_binary) strcat(acc,"b"); // binary mode
}
DWORD WINAPI HandleSocket(void *prm)
{
SOCKET s = (SOCKET)prm;
int ret,len;
char buf[4096];
int *icmnd;
int recvfile;
FILE *File;
int fileno,reject;
CString filename;
char access[32];
char sts[32];
int item;
int total=0;
char vl[64];
char path[512],adjusted[512],opath[512];
char *filenm;
int i;
bool Console=false;
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, bOptLen); // detect when other end fails
pDlg->IncFiles();
// first of all get the length of the header
ret = recv(s,(char *)&len,4,0);
if (ret==4) {
// read the rest of the data
ret = recv(s,buf,len,0);
if (ret == len) {
// we have a filename and a mode
buf[len] = 0;
icmnd = (int *)buf;
SetAccess(icmnd[0],access);
recvfile = (access[0]!='r');
filename = buf+4;
if (strcmp(filename,"con:")==0 ) {
reject = !recvfile;
Console = true;
strcpy(adjusted,filename);
sts[0] = (reject?'R':'A');
} else {
path[0] = 0;
pDlg->m_PathCtrl.GetWindowText(opath,sizeof(opath));
// normalise the path
i = 0;
while (opath[i] != 0) {
if (opath[i]=='/') opath[i] = '\\';
i += 1;
}
strcpy(path,opath);
if (i > 0 && opath[i-1] != '\\') {
strcat(path,"\\");
}
strcat(path,filename);
sts[0]='R';
if (GetFullPathName(path,sizeof(adjusted),adjusted,&filenm) > 0) {
if ((strlen(opath)==0) || (memcmp(opath,adjusted,strlen(opath))==0)) {
File = fopen(adjusted,access);
reject = (File == NULL);
if (reject) {
int i =errno;
} else {
fileno = _fileno(File);
sts[0] ='A';
}
} else {
File = NULL;
reject = 1;
}
} else {
File = NULL;
reject = 1;
}
}
sts[1] = 0;
item = pDlg->m_FileListCtrl.GetItemCount();
item = pDlg->m_FileListCtrl.InsertItem(item,sts,0);
if (item>=0) {
pDlg->m_FileListCtrl.SetItemText(item,1,adjusted);
pDlg->m_FileListCtrl.SetItemText(item,2,access);
pDlg->m_FileListCtrl.SetItemText(item,3,"0");
}
if (reject == 0) {
if (recvfile) {
// read from the socket and write the file
while (1) {
ret = recv(s,buf,sizeof(buf),0);
if (ret>0) {
total += ret;
itoa(total/1024,vl,10);
pDlg->m_FileListCtrl.SetItemText(item,3,vl);
if (Console==0) {
len = _write(fileno,buf,ret);
if (len<ret) {
ret = -1;
break;
}
} else {
// write to the console control
// split into lines
char *eol,*nxt;
int lin,linelen;
nxt = buf;
len = ret;
while (len>0) {
eol = nxt;
lin = len;
while ((lin>0) && (*eol != 10)) {
lin--;
eol++;
}
linelen = eol-nxt;
CString cur(nxt,linelen);
pDlg->m_LeftOver += cur;
if (lin>0) {
// we have found the end of a line
pDlg->m_ConsoleCtrl.AddString(pDlg->m_LeftOver);
pDlg->m_LeftOver = "";
pDlg->m_ClearCtrl.EnableWindow(true);
// step over the EOL
len = lin-1;
nxt += (linelen+1);
} else {
break;
}
}
}
}
if (ret<=0) break;
}
if (Console&&(pDlg->m_LeftOver!="")) {
pDlg->m_ConsoleCtrl.AddString(pDlg->m_LeftOver);
pDlg->m_LeftOver = "";
pDlg->m_ClearCtrl.EnableWindow(true);
}
pDlg->m_FileListCtrl.SetItemText(item,0,(ret>=0?"C":"F"));
} else {
// read from the file and write to the socket
while (1) {
ret = _read(fileno,buf,sizeof(buf));
if (ret>0) {
total += ret;
len = send(s,buf,ret,0);
if (len<ret) {
ret = -1;
break;
} else {
itoa(total/1024,vl,10);
pDlg->m_FileListCtrl.SetItemText(item,3,vl);
}
}
if (ret<=0) break;
}
pDlg->m_FileListCtrl.SetItemText(item,0,(ret>=0?"C":"F"));
}
if (!Console)
_close(fileno);
}
closesocket(s);
}
}
pDlg->DecFiles();
return 0;
}
//###################################################################
//
//###################################################################
DWORD WINAPI ConnectionServer(void *prm)
{
int PortNumber = (int)prm;
HANDLE rThread;
SOCKET s,ss;
int ret=0, ret3=0, iAddrSize;
struct sockaddr_in ra,sa;
DWORD threadid;
int thread=0,ik=0;
long int max_wait=30000;
ServerSocket = 0;
Killing = 0;
// create a socket
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
ReportError(IDS_SOCKCREATION,TRUE,0);
} else {
ServerSocket = s;
// Sets members of sockaddr_in
// Initilaize receiver's parameters
memset((char *)&ra,0,sizeof(ra));
ra.sin_family = AF_INET;
ra.sin_addr.s_addr = INADDR_ANY;
ra.sin_port = htons(PortNumber);
// bind the socket
if (bind(s, (struct sockaddr *)&ra, sizeof(ra)) == SOCKET_ERROR) {
ReportError(IDS_BINDFAIL,true,0);
closesocket(s); // tidy up
} else {
// listen
if ( listen(s,25) == SOCKET_ERROR) {
ReportError(IDS_LISTENFAILED,true,0);
closesocket(s);
} else {
while(1) {
struct sockaddr isa;
sa.sin_port = 0;
iAddrSize = sizeof(sa);
// accept anycoming connection
ss = accept(s, (struct sockaddr*)&isa, &iAddrSize);
if( ss == SOCKET_ERROR) {
ReportError(IDS_ACCEPTFAIL,true,GetLastError());
closesocket(ss); // tidy up
if (Killing) break;
} else {
rThread = CreateThread(NULL,4000,HandleSocket,(void *)ss,0,&threadid);
// printf("dispay %d\n", rThread);
if (rThread == NULL)
{
ReportError(IDS_THREADFAIL,false,GetLastError());
} else {
CloseHandle(rThread);
} // End thread
} // End accept
} // End while
}// End listen
} // End bind
closesocket(s);
} // End create socket
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -