
1、是不是必要?
任何一个类型的SQL数据库.NET都有对应的数据连接方法,MySQL, Oracle, SQL Server都可以在ADO.NET中使用。那么就不是很必要。
2、一定要用,怎么用?
这个就相当复杂了,不是说Socket复杂,是你要设计的通讯代码复制,可以说绝对不亚于你所写的程序,所有关键通讯代码既要有数据又要有结构。那么就将服务器端读到的数据转换成XML格式,再在前后增加标识符,如:<!DATA>XML Data <!EOF>
3、有没有可替代的方法?
有,SQL Server可以使用复杂,合并复制、事务复制,不过这个需要你在程序设计之初就要考虑表格的结构,另外复制需要更新,也就是说需要有.NET *** 纵复制事务。
4、其它解决办法?
这里假设你需要绕开版权问题,不希望采购SQL企业版或者标准版程序,那么可以使用MSDE这样的免费版本,这样有一个问题,就是限制了连接的数量,怎么办,可以使用WebSerices,WebSerices是同过XML传递数据的,只要客户端与服务器端都采用相同的数据结构是完全可以不使用ADO.NET连接就可以完成数据传递、修改的。
你的文件中的问题// 会阻塞进程,直到有客户端连接上来为止
// 既然是直到有客户端连接上,那么就要弄明白哪个是与客户端连接的套接字
// sockClient就是与客户端连接的套接字
sockClient = accept(sockServer, (SOCKADDR*)&addrClient, &len)
//接收并打印客户端数据
recv(sockClient, recvBuf, 100, 0)
printf("%s\n", recvBuf)
// 所以此处,应该把sockServer改为sockClient
send(/*sockServer*/sockClient, sendBuf, 100, 0)
PS:服务器客户端通信,是要保持服务器与客户端的连接。
而不能这样立即关闭,如果设置不对,立即关闭,缓冲区的数据是会丢失的。那客户端也就不会再收到数据了。
你可以加Sleep(10000)来测是通信过程
//关闭socket
closesocket(sockClient)
仅供参考// serverTCP.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
using namespace std
long long cnt = 0
void transFile(SOCKET s)
{
printf("新子服务%d......",cnt)
send(s,"welcome to TCP FILE SERVER !",strlen("welcome to TCP FILE SERVER !")+1,0)
char Buf[BUFSIZE]
FILE *fp
//printf("客户端已打开\n请输入存放文件地址:\n")
char FilePath[128]={"0"}
ltoa(cnt,FilePath,10)
if((fp=fopen(FilePath,"wb"))==NULL)
{
printf("文件未打开\n")
return
}
else
{
send(s,"开始传送",strlen("开始传送")+1,0)
//得到文件大小
char Size[20]
long int FileSize=0
recv(s,Size,21,0)
FileSize=atol(Size)
printf("得到文件大小: %d\n",FileSize)
//开始传送
char Block[BUFSIZE]
long int x=0
while (1)
{
x += BUFSIZE
if(x <FileSize)
{
recv(s,Block,BUFSIZE+1,0)
fwrite(Block,1,BUFSIZE,fp)
}
else
{
recv(s,Block,FileSize+BUFSIZE-x+1,0)
printf("文件接收完毕\n")
fwrite(Block,1,FileSize+BUFSIZE-x,fp)
fclose(fp)
break
}
}
}
fclose(fp)
closesocket(s)
}
int _tmain(int argc, _TCHAR* argv[])
{
WORD myVersionRequest
WSADATA wsaData
myVersionRequest=MAKEWORD(1,1)
int err
err = WSAStartup(myVersionRequest,&wsaData)
if (!err)
{
printf("服务器启动......\n")
}
else
{
printf("服务器启动失败!")
exit(0)
}
SOCKET serSocket = socket(AF_INET,SOCK_STREAM,0)//创建了可识别套接字
SOCKADDR_IN addr
addr.sin_family=AF_INET
addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY)//ip地址
addr.sin_port=htons(PORTBASE)//绑定端口
bind(serSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR))//绑定完成
listen(serSocket,ACESIZE)//其中第二个参数代表能够接收的最多的连接数
SOCKADDR_IN clientAddr
int len = sizeof(SOCKADDR)
while(1)
{
cnt++
SOCKET serConn
serConn = accept(serSocket,(SOCKADDR*)&clientAddr,&len)//如果这里不是accept而是conection的话。。就会不断的监听
if(_beginthread((void (*)(void *))transFile, ACESIZE,(void *)serConn) <0) return 0
}
return 0
}
// clientTCP.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
using namespace std
int _tmain(int argc, _TCHAR* argv[])
{
WORD myVersionRequest
WSADATA wsaData
myVersionRequest=MAKEWORD(1,1)
int err
err=WSAStartup(myVersionRequest,&wsaData)
if (!err)
{
printf("已打开套接字\n")
}
else
{
//进一步绑定套接字
printf("套接字未打开!")
return 0
}
SOCKET cliSocket =socket(AF_INET,SOCK_STREAM,0)
SOCKADDR_IN addr
char ip_addr[16]={"127.0.0.1"}
addr.sin_addr.S_un.S_addr=inet_addr(ip_addr)
addr.sin_family=AF_INET
addr.sin_port=htons(PORT)
char ACK[64]
connect(cliSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR))//开始连接
recv(cliSocket,ACK,sizeof(ACK),0)
printf("%s\n",ACK)
FILE *fp
int FileSize=0
char Block[BUFSIZE]={"0"}
char FilePath[128]={"0"}
int i=0
do
{
printf("请输入文件地址:\n")
gets(FilePath)
i = 0
if((fp=fopen(FilePath,"rb"))==NULL)
{
i = 1
printf("文件打开失败\n")
}
}while(i)
fseek(fp,0L,SEEK_END)
FileSize=ftell(fp)
printf("待传送文件大小: %d\n",FileSize)
printf("等待服务器接受......\n")
recv(cliSocket,Block,sizeof(Block),0)
printf("%s\n",Block)
if(strcmp(Block,"开始传送")==0)
{
char Size[20]
ltoa(FileSize,Size,10)
send(cliSocket,Size,sizeof(Size),0)
fseek(fp,0L,SEEK_SET)
long int y=0
char trans[BUFSIZE]
while(!feof(fp))
{
fread(trans,1,BUFSIZE,fp)
y=y+BUFSIZE
if(y<FileSize)
{
send(cliSocket,trans,BUFSIZE+1,0)
}
else
{
send(cliSocket,trans,FileSize+BUFSIZE-y+1,0)
closesocket(cliSocket)
WSACleanup()
}
}
}
printf("文件发送完毕\n")
fclose(fp)
closesocket(cliSocket)
WSACleanup()
system("pause")
return 0
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)