當前位置:首頁 » 操作系統 » udp文件傳輸源碼

udp文件傳輸源碼

發布時間: 2022-10-10 02:48:44

㈠ 誰能給我一個基於DUP協議的可靠數據傳輸的源代碼

如何用vb的winsocket解決udp文件傳送丟包的問題

udp協議是1種無連接的協議,他和tcp協議比較有傳輸速度快,佔用資源少的問題。
但是由於udp協議本身沒有自動找包的功能,因此經常會出現丟包的現象,會造成傳送的文件丟包的現象
因為時間匆忙和水平有限,本人在效率上沒有作優化,只是簡單的實現,請大家自己看源碼
注釋:
主要功能:把文件猜成4k大小的包 在包頭+上包的長度 接受了1個包判斷長度是否和接受的長度相符如果

符合那麼就繼續發,如果出現丟包那麼就從發
希望大家有什麼好的建議通知我,我會盡量完善的
Option Explicit
'==============================================
'===============================
'udp傳文件
'客戶端
'作者: 影子
'================================
'==============================================
Dim FileNumber As Integer '用來存文件的句柄
Dim LenFile As Long '文件的長度
Private Sub Command2_Click()
closefile
End Sub

Private Sub Form_Load()
Winsock0.LocalPort = 5698
Winsock0.Bind
beginfile
End Sub
Private Sub Winsock0_DataArrival(ByVal bytesTotal As Long)
Dim FileByte() As Byte
Winsock0.GetData FileByte, vbArray + vbByte '接收類型為:位元組數組
Dim mendByte() As Byte, i As Long, j As Long
Dim temp As String, temp1 As String
'獲得包長
j = UBound(FileByte)
'合並包頭
For i = 0 To 7 Step 2
temp = temp & Chr(FileByte(i))
Next
'比較長度看丟包沒有
If Val(temp) = j Then

ReDim mendByte(j - 8)
' 提出包頭
For i = 0 To j - 8
mendByte(i) = FileByte(i + 7)
Next
' 寫文件
Put #FileNumber, , mendByte
' 發送繼續發送的請求
frmmain.Winsock0.SendData "ok"
Else
'出現丟包,請求重發
frmmain.Winsock0.SendData "no"
End If
End Sub

Public Sub beginfile()
FileNumber = FreeFile '取得未使用的文件號
Open "c:\aaa.exe" For Binary As #FileNumber '打開文件
End Sub

Public Sub closefile() '關閉文件句柄
Close #FileNumber
End Sub

Option Explicit
Dim GetFileNum As Integer
Dim LenFile As Long
Dim Sendbaye() As Byte '發送的包
'===============================
'udp傳文件
'作者: 影子
'伺服器端
'================================

Private Sub Command1_Click()
GetFileNum = FreeFile '取得未使用的文件號
LenFile = FileLen("d:\aa.rar") '獲得需傳送的文件的長度
Open "d:\aa.rar" For Binary As #GetFileNum '打開需傳送的文件
Command1.Enabled = False
' 傳送文件
Call TCPSendFile(frmmain.Winsock0, GetFileNum, SplitFile)
Text1.Text = Now
End Sub

Private Sub Form_Load()
frmmain.Winsock0.RemoteHost = "192.168.0.12" '伺服器ip
frmmain.Winsock0.RemotePort = 5698

End Sub
'=========================================================================
'為了清晰,下面分別用兩個子過程來完成計算這次還可以傳多少個位元組的數據和傳送數據
'==========================================================================
Private Function SplitFile() As Long '拆包
On Error Resume Next
Dim GetCount As Long
'計算出這次可發送的位元組數
If LenFile >= 4000 Then
GetCount = 4000
LenFile = LenFile - GetCount
Else
GetCount = LenFile
LenFile = LenFile - GetCount
End If
SplitFile = GetCount

End Function
Private Sub TCPSendFile(objWinSock As Winsock, FileNumber As Integer, SendLen As Long)
Dim FileByte() As Byte, i As Long, j As Long
Dim temp As String
ReDim Sendbaye(0)

Dim tempa As String * 4
ReDim FileByte(SendLen - 1)
tempa = SendLen + 7
Sendbaye = tempa ' 把長度負值給包頭
Get #FileNumber, , FileByte '讀取文件
ReDim Preserve Sendbaye(SendLen + 7) '把包頭+到文件頭
For i = 0 To UBound(FileByte)
Sendbaye(i + 7) = FileByte(i)
Next
frmmain.Winsock0.SendData Sendbaye
End Sub

Private Sub Winsock0_DataArrival(ByVal bytesTotal As Long)
Dim str As String
frmmain.Winsock0.GetData str
Select Case str
Case "ok"
'成功繼續發送
If LenFile = 0 Then '發送完成
MsgBox "成功"
Exit Sub
End If
Call TCPSendFile(frmmain.Winsock0, GetFileNum, SplitFile)
Case "no"
'不成功重發上一個包
frmmain.Winsock0.SendData Sendbaye
End Select
End Sub

㈡ C語言 UDP文件傳輸

void ThreadReceive(PVOID param)
{
static struct sockaddr_in server; // 綁定地址
static SOCKET ListenSocket; // 等待接收數據的socket
char buf[4096];
int len = sizeof(client);
int result;

ListenSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

if (ListenSocket == INVALID_SOCKET)
{
perror("opening stream socket");
exit(0);
}

server.sin_family = PF_INET;
server.sin_addr.s_addr = htonl( INADDR_ANY ); // 任何地址
server.sin_port = htons(LOCAL_PORT);

if (SOCKET_ERROR == bind(ListenSocket, (struct sockaddr *)&server, sizeof(server)) )
{
printf("Error: 綁定失敗\n");
exit(1);
closesocket( ListenSocket );
}
printf("socket port %d \n", ntohs(server.sin_port));

while(TRUE)
{
//接收數據
result = recvfrom(ListenSocket, buf, sizeof(buf)-1, 0, (struct sockaddr *)&client, &len);
if ( result > 0 )
{
buf[result] = 0;
inet_ntoa(client.sin_addr), ntohs(client.sin_port));
}
}
closesocket(ListenSocket);
}

㈢ 求一個UDP套接字文件傳輸的C/C++代碼

你的問題是一個偽命題!
如果不用TCP/IP協議,自己寫底層協議的話,基本上不可實現:
1)你需要編寫驅動網卡的驅動程序---涉及操作系統內核編程
2)你需要定義自己的應用協議模塊,該模塊調用網卡驅動,從頭造輪子,屬於重復工作,在現在來說,基本沒什麼意義!

㈣ 請教用C語言編的藉助UDP協議實現的文件傳輸的程序

server代碼
#include<sys/socket.h>;
#include<string.h>;
#include<netinet/in.h>;
#include<stdio.h>;
#include<stdlib.h>;
#include<fcntl.h>;
#include<sys/stat.h>;
#include<unistd.h>;
#include<errno.h>;
#include<sys/select.h>;
#include<sys/time.h>;
#include<unistd.h>;
#include<sys/types.h>;

#define SERV_PORT 2500
#define MAX_SIZE 1024*40

void recvUDP(char name[20],int sockfd)
{
int ret,fd;
mode_t fdmode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
char mesg[MAX_SIZE];
fd_set rdset;
struct timeval tv;
int rlen,wlen;
int i;

fd = open(name,O_RDWR|O_CREAT|O_APPEND,fdmode);
if(fd == -1)
{
printf("open file %s error:%n",name,strerror(errno));
exit(-1);
}

for(i=0;;i++)
{
tv.tv_sec = 1;
tv.tv_usec = 0;

FD_ZERO(&rdset);
FD_SET(sockfd,&rdset);

ret = select(sockfd+1,&rdset,NULL,NULL,&tv);
if(ret == -1)
{
printf("select error %s\n",strerror(errno));
exit(-1);
}
else if(ret==0)
{
printf("select timeout,continue circle\n");
continue;
}

if(FD_ISSET(sockfd,&rdset))
{
memset(mesg,0,MAX_SIZE);
rlen = read(sockfd,mesg,MAX_SIZE);
if(rlen <=0 )
{
printf("read error %s\n",strerror(errno));
exit(-1);
}

if(!strcmp(mesg,"end"))
{
printf("recv end.\n");
break;
}

wlen = write(fd,mesg,rlen);
if(wlen != rlen )
{
printf("write error %s\n",strerror(errno));
exit(-1);
}
}

printf("The %d times write\n",i);
}

close(fd);
}

int main(int argc, char *argv[])
{
int sockfd;
int r;
struct sockaddr_in servaddr;

sockfd = socket(AF_INET,SOCK_DGRAM,0); /*create a socket*/

/*init servaddr*/
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);

/*bind address and port to socket*/
if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) == -1)
{
perror("bind error");
exit(-1);
}

r = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, r & ~O_NONBLOCK);

recvUDP(argv[1],sockfd);

return 0;

}
client代碼
#include<sys/types.h>;
#include<sys/socket.h>;
#include<string.h>;
#include<netinet/in.h>;
#include<stdio.h>;
#include<stdlib.h>;
#include<arpa/inet.h>;
#include<fcntl.h>;
#include<sys/stat.h>;
#include<errno.h>;
#include<sys/sysinfo.h>;
#include<sys/select.h>;
#include<sys/time.h>;
#include<unistd.h>;

#define MAX_SIZE 1024*40
#define SERV_PORT 2500

void connectUDP(char name[20],int sockfd,struct sockaddr *pservaddr,socklen_t servlen)
{
char buf[MAX_SIZE];
fd_set wrset;
struct timeval tv;
int rlen,wlen;
int fd;
int ret;
int i;

if(connect(sockfd,(struct sockaddr *)pservaddr,servlen) == -1)
{
perror("connet error");
exit(1);
}
else
printf("connect server ok!\n");

fd = open(name,O_RDONLY);
if(fd==-1)
{
printf("fopen error %s\n",strerror(errno));
exit(-1);
}

i=0;

while(1)
{
tv.tv_sec = 1;
tv.tv_usec = 0;

FD_ZERO(&wrset);
FD_SET(sockfd,&wrset);

ret = select(sockfd+1,NULL,&wrset,NULL,&tv);
if(ret == -1)
{
printf("select error %s\n",strerror(errno));
exit(-1);
}
else if(ret==0)
{
printf("select timeout,continue circle\n");
continue;
}

memset(buf,0,MAX_SIZE);
if(FD_ISSET(sockfd,&wrset))
{
rlen = read(fd,buf,MAX_SIZE);
if(rlen <0)
{
printf("fread data error %s\n",strerror(errno));
exit(-1);
}
else if(rlen==0)
{
wlen = write(sockfd,"end",3);
if(wlen !=3)
{
printf("write end error\n",strerror(errno));
exit(-1);
}

printf("all complete\n");

close(fd);
close(sockfd);
exit(0);
}

wlen = write(sockfd,buf,rlen);
if(wlen != rlen)
{
printf("write data to sockfd error:%s\n",strerror(errno));
exit(-1);
}

i++;

usleep(500);
printf("The %d times read\n",i);
}
}
}

int main(int argc ,char *argv[])
{
char *fh;
struct sysinfo s_info;
float time1,time2;
int error1,error2;
int sockfd;
struct stat fsize;
struct sockaddr_in servaddr;
error1= sysinfo(&s_info);
time1 = s_info.uptime;
int r;

if(argc != 3)
{
printf("useage:udpclient<IPaddress>;\n");
exit(1);
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family= AF_INET;
servaddr.sin_port = htons(SERV_PORT);

if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr) <= 0)
{
printf("[%s]is not a valid IPaddress\n",argv[1]);
exit(1);
}
fh = argv[2];

sockfd =socket(AF_INET,SOCK_DGRAM,0);

r = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, r & ~O_NONBLOCK);

connectUDP(argv[2],sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
fprintf(stderr,"ServerIP:\t%s\n",argv[1]);
if(stat(argv[2],&fsize) == -1)
perror("failed to get fiel statusi\n");
else
fprintf(stderr,"file name:\t%s\nfile size:\t%dK\n",argv[2],fsize.st_size/1024);
error2=sysinfo(&s_info);
time2 = s_info.uptime;
printf("tranfice file time =%fs\n",(time2-time1));
}
makefile
all:send recv

send:send.c
gcc -Wall send.c -o send
recv:recv.c
gcc -Wall recv.c -o recv

clean:
rm -rf send recv

㈤ 請教用C語言編的藉助UDP協議實現的文件傳輸的程序

本程序在 Windows 7 Visual Studio 2015 和 linux Ubuntu 15.04 GCC 5.11 下均編譯運行測試通過。

本程序支持 Windows 和 Linux 之間傳送文件,如果要在 Windows 和 Linux 之間傳送文件,文件名不能出現中文。

本程序支持無線 WiFi,支持 USB 收發器,但僅支持區域網內傳送文件,傳送文件需要輸入對方的 IP 地址。

本程序包括伺服器端和客戶端,既可以發送文件又可以接收文件。如果要在同一台機器上測試需要同時打開兩個程序。

Windows 下查看本機 IP 地址的命令是:

ipconfig

Linux 下查看本機 IP 地址的命令是:

ifconfig

以下是程序代碼:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

#ifdef_MSC_VER
#include<winsock2.h>
#include<windows.h>
#pragmacomment(lib,"ws2_32.lib")
#else
#include<pthread.h>
#include<unistd.h>
#include<signal.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#endif

//存放發送接收字元數組大小
#defineSIZEA65501
//每次發送接收位元組數
#defineSIZEB65500

typedefstructsockaddr_inSockAddrIn;
SockAddrInserverAddr,remoteAddr,clientAddr;

//埠號
intiServerPort,iClientPort;
//新建socket信息
intiUDP;

//字元串轉整型
intstrToInt(char*acStr)
{
inti,iIndex=0,iNum=0,iSize=0;
if(acStr[0]=='+'||acStr[0]=='-')
iIndex=1;

for(iSize=iIndex;;iSize++)
if(acStr[iSize]<'0'||acStr[iSize]>'9')
break;

for(i=iIndex;i<iSize;i++)
iNum+=(int)pow(10,iSize-i-1)*(acStr[i]-48);

if(acStr[0]=='-')
iNum=-iNum;

returniNum;
}

//整型轉字元串
voidintToStr(intiInt,char*acStr)
{
intiIndex=0,iSize,iNum,iBit,i,j;

if(iInt<0)
{
acStr[0]='-';
iInt=-iInt;
iIndex=1;
}
for(i=0;;i++)
if(iInt<pow(10,i))
break;
iSize=i;

for(i=0;i<iSize;i++)
{
iNum=pow(10,iSize-i-1);
iBit=iInt/iNum;
iInt-=iNum*iBit;
acStr[i+iIndex]=iBit+48;
}
if(iSize!=0)
acStr[iSize+iIndex]='';
else
{
acStr[0]='0';
acStr[1]='';
}
}

voidsleepUDP(intiSleep)
{
#ifdef_MSC_VER
Sleep(iSleep);
#else
usleep(iSleep*1000);
#endif
}

voidopenUDP(char*acIpAddr)
{
#ifdef_MSC_VER
//Winsows啟用socket
WSADATAwsadata;
if(WSAStartup(MAKEWORD(1,1),&wsadata)==SOCKET_ERROR)
{
printf("啟用socket失敗 ");
exit(0);
}
#endif

//新建socket
if((iUDP=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1)
{
printf("新建socket失敗 ");
exit(0);
}

//清零
memset(&serverAddr,0,sizeof(serverAddr));
memset(&clientAddr,0,sizeof(clientAddr));

//設置協議IP地址及Port
serverAddr.sin_family=AF_INET;
serverAddr.sin_port=htons(iServerPort);
serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);

clientAddr.sin_family=AF_INET;
clientAddr.sin_port=htons(iClientPort);
clientAddr.sin_addr.s_addr=inet_addr(acIpAddr);

//綁定埠,監聽埠
if(bind(iUDP,(structsockaddr*)&serverAddr,sizeof(serverAddr))==-1)
{
printf("綁定埠失敗 ");
exit(0);
}
}

voidcloseUDP(void)
{
#ifdef_MSC_VER
//Winsows關閉socket
closesocket(iUDP);
WSACleanup();
#endif
}

//要發送的字元串
characSendStr[SIZEA];
//接收到的字元串
characRecvStr[SIZEA];
//請求信息
characReq[SIZEA];
//文件名字元串
characFileName[SIZEA];
//文件位元組數字元串
characFileSize[SIZEA];

intiSize,iNameSize;

//接收文件名
#ifdef_MSC_VER
DWORDWINAPIrecvName(LPVOIDp)
#else
void*recvName(void*arg)
#endif
{
intiAddrSize=sizeof(remoteAddr);
acReq[0]='n';acReq[1]='a';acReq[2]='m';acReq[3]='e';acReq[4]='';
acRecvStr[0]='';
printf("%s ","正在發送請求信息!");
//發送請求信息
sendto(iUDP,acReq,strlen(acReq),0,(structsockaddr*)&clientAddr,sizeof(clientAddr));
//每次發送請求信息後等待一段時間
sleepUDP(10);
//接收文件名
iSize=recvfrom(iUDP,acRecvStr,SIZEB,0,(structsockaddr*)&remoteAddr,&iAddrSize);
return0;
}

//接收文件
voidrecvFile(char*acDirName,char*acIpAddr)
{
FILE*pFile=NULL;
inti,iFileSize,iRecvNum,iAddrSize=sizeof(remoteAddr);
//路徑文件名
characDirAndFileName[SIZEA];

openUDP(acIpAddr);
//接收文件名
for(;;)
{
//創建線程
#ifdef_MSC_VER
HANDLEhThread;
DWORDthreadId;
hThread=CreateThread(NULL,0,recvName,0,0,&threadId);
//每次發送後等待一段時間
sleepUDP(1000);
//強制終止線程
TerminateThread(hThread,0);
#else
pthread_tthread;
void*thread_arg=(pthread_t)0;
pthread_create(&thread,NULL,recvName,(void*)&thread_arg);
//每次發送後等待一段時間
sleepUDP(1000);
//強制終止線程
pthread_cancel(thread);
#endif
if(acRecvStr[0]!='')
{
acRecvStr[iSize]='';
printf("文件名為:%s ",acRecvStr);
break;
}
}

acDirAndFileName[0]='';
strcat(acDirAndFileName,acDirName);
//連接路徑名和文件名
strcat(acDirAndFileName,acRecvStr);
//如果已經有這個文件了就清空文件內容
pFile=fopen(acDirAndFileName,"w");
fclose(pFile);

acReq[0]='s';acReq[1]='i';acReq[2]='z';acReq[3]='e';acReq[4]='';
//接收文件位元組數
for(;;)
{
//發送請求信息
sendto(iUDP,acReq,strlen(acReq)+1,0,(structsockaddr*)&clientAddr,sizeof(clientAddr));
//每次發送請求信息後等待一段時間
sleepUDP(10);
//接收文件位元組數
acRecvStr[0]='';
iSize=recvfrom(iUDP,acRecvStr,SIZEB,0,(structsockaddr*)&remoteAddr,&iAddrSize);
if(acRecvStr[0]!='')
{
acRecvStr[iSize]='';
iFileSize=strToInt(acRecvStr);
printf("文件位元組數為:%d ",iFileSize);
break;
}
}

//以追加方式寫入文件
pFile=fopen(acDirAndFileName,"ab");
//文件分幾次接收
iRecvNum=iFileSize/SIZEB;
//接收文件
for(i=0;i<iRecvNum;i++)
{
intToStr(i,acReq);
for(;;)
{
//發送請求信息
sendto(iUDP,acReq,strlen(acReq)+1,0,(structsockaddr*)&clientAddr,sizeof(clientAddr));
printf("%s 正在接收文件的第%d段 ",acReq,i);
//每次發送請求信息後等待一段時間
sleepUDP(10);
//接收一段文件
iSize=recvfrom(iUDP,acRecvStr,SIZEB,0,(structsockaddr*)&remoteAddr,&iAddrSize);
if(iSize==SIZEB)
{
//以追加方式寫入文件
fwrite(acRecvStr,sizeof(char),iSize,pFile);
break;
}
}
}
//接收文件剩餘位元組
iSize=iFileSize%SIZEB;
if(iSize>0)
{
acReq[0]='l';acReq[1]='a';acReq[2]='s';acReq[3]='t';acReq[4]='';
for(;;)
{
//發送請求信息
sendto(iUDP,acReq,strlen(acReq)+1,0,(structsockaddr*)&clientAddr,sizeof(clientAddr));
//每次發送請求信息後等待一段時間
sleepUDP(10);
//接收文件剩餘位元組
if(recvfrom(iUDP,acRecvStr,iSize,0,(structsockaddr*)&remoteAddr,&iAddrSize)==iSize)
{
//以追加方式寫入文件
fwrite(acRecvStr,sizeof(char),iSize,pFile);
break;
}
}
}
printf("%s ","文件接收完畢!");

//關閉文件
fclose(pFile);
//關閉連接
closeUDP();
}

//發送文件名
#ifdef_MSC_VER
DWORDWINAPIsendName(LPVOIDp)
#else
void*sendName(void*arg)
#endif
{
intiAddrSize=sizeof(remoteAddr);
acRecvStr[0]='';
//接收請求
printf("%s ","正在接收請求信息!");
recvfrom(iUDP,acRecvStr,5,0,(structsockaddr*)&remoteAddr,&iAddrSize);
//每次接收請求信息後等待一段時間
sleepUDP(10);
//如果請求信息正確發送文件名
if(acRecvStr[0]=='n'&&acRecvStr[1]=='a'&&acRecvStr[2]=='m'&&acRecvStr[3]=='e'&&acRecvStr[4]=='')
sendto(iUDP,acFileName,iNameSize,0,(structsockaddr*)&clientAddr,sizeof(clientAddr));
return0;
}

//發送文件
voidsendFile(char*acDirAndFileName,char*acIpAddr)
{
inti,j,iFileSize,iSendNum,iAddrSize=sizeof(remoteAddr);
FILE*pFile=NULL;

pFile=fopen(acDirAndFileName,"rb");
fseek(pFile,0,SEEK_END);
//文件位元組數
iFileSize=ftell(pFile);
intToStr(iFileSize,acFileSize);
//printf("%s ",acDirAndFileName);

//獲取文件名長度
iSize=strlen(acDirAndFileName);
for(i=iSize-1,iNameSize=0;i>=0;i--,iNameSize++)
if(acDirAndFileName[i]=='\'||acDirAndFileName[i]=='/')
break;
//printf("%d ",iNameSize);

//截取文件名
for(i=0;i<iNameSize;i++)
acFileName[i]=acDirAndFileName[iSize-iNameSize+i];
acFileName[iNameSize]='';
//printf("%s ",acFileName);

openUDP(acIpAddr);
//發送文件名
for(;;)
{
//創建線程
#ifdef_MSC_VER
HANDLEhThread;
DWORDthreadId;
hThread=CreateThread(NULL,0,sendName,0,0,&threadId);
//每次接收請求信息後等待一段時間
sleepUDP(1000);
//強制終止線程
TerminateThread(hThread,0);
#else
pthread_tthread;
void*thread_arg=(pthread_t)0;
pthread_create(&thread,NULL,sendName,(void*)&thread_arg);
//每次接收請求信息後等待一段時間
sleepUDP(1000);
//強制終止線程
pthread_cancel(thread);
#endif
//如果請求信息正確退出循環
if(acRecvStr[0]=='n'&&acRecvStr[1]=='a'&&acRecvStr[2]=='m'&&acRecvStr[3]=='e'&&acRecvStr[4]=='')
break;
}
//發送文件位元組數
for(;;)
{
acRecvStr[0]='';
//接收請求
recvfrom(iUDP,acRecvStr,5,0,(structsockaddr*)&remoteAddr,&iAddrSize);
//每次接收請求信息後等待一段時間
sleepUDP(10);
//如果請求信息正確
if(acRecvStr[0]=='s'&&acRecvStr[1]=='i'&&acRecvStr[2]=='z'&&acRecvStr[3]=='e'&&acRecvStr[4]=='')
{
//發送文件位元組數
sendto(iUDP,acFileSize,strlen(acFileSize),0,(structsockaddr*)&clientAddr,sizeof(clientAddr));
break;
}
}

iSendNum=iFileSize/SIZEB;
//發送文件
if(iSendNum>0)
{
for(i=0;;i++)
{
acRecvStr[0]='';
//接收請求
recvfrom(iUDP,acRecvStr,SIZEB,0,(structsockaddr*)&remoteAddr,&iAddrSize);
printf("%s 正在發送文件的第%d段 ",acRecvStr,i);
//每次接收請求信息後等待一段時間
sleepUDP(10);
fseek(pFile,strToInt(acRecvStr)*SIZEB,SEEK_SET);
fread(acSendStr,1,SIZEB,pFile);
//printf("%s ",acSendStr);
//發送一段文件
sendto(iUDP,acSendStr,SIZEB,0,(structsockaddr*)&clientAddr,sizeof(clientAddr));
if(strToInt(acRecvStr)>=iSendNum-1)
break;
}
}
//發送文件剩餘位元組
iSize=iFileSize%SIZEB;
if(iSize>0)
{
for(;;)
{
acRecvStr[0]='';
//接收請求
recvfrom(iUDP,acRecvStr,5,0,(structsockaddr*)&remoteAddr,&iAddrSize);
//每次接收請求信息後等待一段時間
sleepUDP(10);
//如果請求信息正確
if(acRecvStr[0]=='l'&&acRecvStr[1]=='a'&&acRecvStr[2]=='s'&&acRecvStr[3]=='t'&&acRecvStr[4]=='')
{
fseek(pFile,iSendNum*SIZEB,SEEK_SET);
fread(acSendStr,1,iSize,pFile);
//printf("%s ",acSendStr);
//發送文件剩餘位元組
sendto(iUDP,acSendStr,iSize,0,(structsockaddr*)&clientAddr,sizeof(clientAddr));
break;
}
}
}
printf("%s ","文件發送完畢!");

//關閉連接
closeUDP();
}

intmain(void)
{
characDirName[SIZEA];
characDirAndFileName[SIZEA];
characIpAddr[15];
inti,iOption=0,iSize=0;
FILE*pFile=NULL;
charcLast='\';

option:
printf("%s ","**************************************************** 本程序包括伺服器端和客戶端,既可以發送文件又可以接收文件。 支持無線WiFi,支持USB收發器,但僅支持區域網內傳送文件。 如果要在Windows和Linux之間傳送文件,文件名不能出現中文。 如果要在同一台機器上測試需要同時打開兩個程序。 ****************************************************");
printf("%s ","請輸入選項,1.發送文件、2.接收文件。");
scanf("%d",&iOption);

//發送文件
if(iOption==1)
{
iServerPort=1025;
iClientPort=1024;
fileName:
printf("%s ","請輸入需要發送的路徑文件名。 Windows路徑文件名格式: C:\install.txt Linux路徑文件名格式: /home/install.txt");
scanf("%s",acDirAndFileName);
pFile=fopen(acDirAndFileName,"rb");
if(pFile==NULL)
{
printf("%s ","讀取文件失敗,請重新輸入文件名。");
gotofileName;
}
//關閉文件
fclose(pFile);

printf("%s ","請輸入接收文件方的IP地址,不能有空格。 例如: 192.168.1.104");
scanf("%s",acIpAddr);

sendFile(acDirAndFileName,acIpAddr);
}
//接收文件
elseif(iOption==2)
{
iServerPort=1024;
iClientPort=1025;
dirName:
printf("%s ","請輸入保存文件的路徑名。 Windows路徑名格式: C:\img\ Linux路徑名格式: /home/");
scanf("%s",acDirName);

iSize=strlen(acDirName);
//檢查是不是Linux路徑名
for(i=0;i<iSize;i++)
{
if(acDirName[i]=='/')
{
cLast='/';
break;
}
}
//檢查路徑名最後一個字元是不是或/
if(acDirName[iSize-1]!=cLast)
{
acDirName[iSize]=cLast;
acDirName[iSize+1]='';
}
acDirAndFileName[0]='';
strcat(acDirAndFileName,acDirName);
strcat(acDirAndFileName,"a.txt");
//試探保存一個無關緊要的文件
pFile=fopen(acDirAndFileName,"w");
if(pFile==NULL)
{
printf("%s ","該路徑無法創建文件,請重新輸入路徑名。");
gotodirName;
}
else
{
//關閉文件
fclose(pFile);
//刪除文件
remove(acDirAndFileName);
}

printf("%s ","請輸入發送文件方的IP地址,不能有空格。 例如: 192.168.2.249");
scanf("%s",acIpAddr);

recvFile(acDirName,acIpAddr);
}
else
{
printf("%s ","沒有這個選項,請重新輸入。");
gotooption;
}

return0;
}

㈥ C#udp文件傳輸程序

使用UDP協議進行文件傳輸不能保證正確性,很容易發生丟包的情況。建議在進行較大文件傳輸的時候使用TCP的Socket和ServerSocket類進行傳輸。在數據量小於65600位元組的時候使用UDP是安全的

如果一定要使用UDP方式進行傳輸的話,為了提高傳輸的准確性,可以限制一下傳輸速度,方法是在發送端每次發送後sleep一下,即在發送端程序的dataSocket.send(dataPacket);一句後加上:
TimeUnit.MICROSECONDS.sleep(1);
不過這種方法也不能保證傳輸絕對准確,所以還是建議用TCP的方式

程序本身應該是能夠達到效果的,不知道錯誤提示是什麼。測試之前要看下發送端的filePath文件是否存在,貌似防火牆也有影響,測試之間最好關閉防火牆。下面是我的測試程序,接收端是類A1,接收端是類A2,發送端的文件filePath是D盤根目錄下的a1.mkv:

接收端:
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class A1 {
public static DatagramSocket dataSocket;
public static final int PORT=7;
public static byte[] receiveByte;
public static DatagramPacket dataPacket;
public static void main(String[] args) throws IOException{
dataSocket = new DatagramSocket(PORT);
DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream("D:\\a.mkv"))));
int i = 0;
while (i == 0)// 無數據,則循環

{
receiveByte = new byte[1024];
dataPacket = new DatagramPacket(receiveByte, receiveByte.length);
dataSocket.receive(dataPacket);
i = dataPacket.getLength();
// 接收數據

if (i > 0) {
// 指定接收到數據的長度,可使接收數據正常顯示,開始時很容易忽略這一點

fileOut.write(receiveByte,0,i);
fileOut.flush();
i = 0;// 循環接收
}

}
}
}

發送端:

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.util.Date;

public class A2 {
public static DatagramSocket dataSocket;
public static final int PORT=7;
public static byte[] sendDataByte;
public static DatagramPacket dataPacket;
public static void main(String[] args) throws IOException, InterruptedException{
String filePath="D:\\a1.mkv";
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
dataSocket = new DatagramSocket(PORT+1);
sendDataByte = new byte[1024];
int read=0;
long a=new Date().getTime();
while(true){
if (fis != null) {
read = fis.read(sendDataByte);
}

if (read == -1) {
System.out.println(new Date().getTime()-a);
break;
}
dataPacket = new DatagramPacket(sendDataByte, sendDataByte.length,(Inet4Address) Inet4Address.getByName("localhost"), PORT);
dataSocket.send(dataPacket);
TimeUnit.MICROSECONDS.sleep(1);//限制傳輸速度
}
}
}

㈦ C#udp文件傳輸程序

為什麼在創建了Udp方式的Socket類後,還繼續創建一個 Udpclient去進行傳輸。直接用 Socket的ReceiveFrom不就可以了么?
Socket newsock=.....
newsock.ReceiveFrom(...

㈧ Go 語言自我提升 (三次握手 - 四次揮手 - TCP狀態圖 - udp - 網路文件傳輸)

三次握手:

            1. 主動發起連接請求端(客戶端),發送 SYN 標志位,攜帶數據包、包號

            2. 被動接收連接請求端(伺服器),接收 SYN,回復 ACK,攜帶應答序列號。同時,發送SYN標志位,攜帶數據包、包號

            3. 主動發起連接請求端(客戶端),接收SYN 標志位,回復 ACK。

                        被動端(伺服器)接收 ACK —— 標志著 三次握手建立完成( Accept()/Dial() 返回 )

四次揮手:

            1. 主動請求斷開連接端(客戶端), 發送 FIN標志,攜帶數據包

            2. 被動接受斷開連接端(伺服器), 發送 ACK標志,攜帶應答序列號。 —— 半關閉完成。

            3. 被動接受斷開連接端(伺服器), 發送 FIN標志,攜帶數據包

            4. 主動請求斷開連接端(客戶端), 發送 最後一個 ACK標志,攜帶應答序列號。—— 發送完成,客戶端不會直接退出,等 2MSL時長。

                        等 2MSL待目的:確保伺服器 收到最後一個ACK

滑動窗口:

            通知對端本地存儲數據的 緩沖區容量。—— write 函數在對端 緩沖區滿時,有可能阻塞。

TCP狀態轉換:

            1. 主動發起連接請求端:

                        CLOSED ——> 發送SYN ——> SYN_SENT(了解) ——> 接收ACK、SYN,回發 ACK ——> ESTABLISHED (數據通信)

            2. 主動關閉連接請求端:

                        ESTABLISHED ——> 發送FIN ——> FIN_WAIT_1 ——> 接收ACK ——> FIN_WAIT_2 (半關閉、主動端)

                        ——> 接收FIN、回復ACK ——> TIME_WAIT (主動端) ——> 等 2MSL 時長 ——> CLOSED

            3. 被動建立連接請求端:

                        CLOSED ——> LISTEN ——> 接收SYN、發送ACK、SYN ——> SYN_RCVD ——> 接收 ACK ——> ESTABLISHED (數據通信)

            4. 被動斷開連接請求端:

                        ESTABLISHED ——> 接收 FIN、發送 ACK ——> CLOSE_WAIT ——> 發送 FIN ——> LAST_ACK ——> 接收ACK ——> CLOSED

windows下查看TCP狀態轉換:

            netstat -an | findstr  埠號

Linux下查看TCP狀態轉換:

            netstat -an | grep  埠號

TCP和UDP對比: 

            TCP: 面向連接的可靠的數據包傳遞。 針對不穩定的 網路層,完全彌補。ACK

            UDP:無連接不可靠的報文傳輸。 針對不穩定的 網路層,完全不彌補。還原網路真實狀態。

                                    優點                                                             缺點

            TCP: 可靠、順序、穩定                                      系統資源消耗大,程序實現繁復、速度慢

            UDP:系統資源消耗小,程序實現簡單、速度快                          不可靠、無序、不穩定

使用場景:

            TCP:大文件、可靠數據傳輸。 對數據的 穩定性、准確性、一致性要求較高的場合。

            UDP:應用於對數據時效性要求較高的場合。 網路直播、電話會議、視頻直播、網路游戲。

UDP-CS-Server實現流程:

            1.  創建 udp地址結構 ResolveUDPAddr(「協議」, 「IP:port」) ——> udpAddr 本質 struct{IP、port}

            2.  創建用於 數據通信的 socket ListenUDP(「協議」, udpAddr ) ——> udpConn (socket)

            3.  從客戶端讀取數據,獲取對端的地址 udpConn.ReadFromUDP() ——> 返回:n,clientAddr, err

            4.  發送數據包給 客戶端 udpConn.WriteToUDP("數據", clientAddr)

UDP-CS-Client實現流程:

            1.  創建用於通信的 socket。 net.Dial("udp", "伺服器IP:port") ——> udpConn (socket)

            2.  以後流程參見 TCP客戶端實現源碼。

UDPserver默認就支持並發!

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

命令行參數: 在main函數啟動時,向整個程序傳參。 【重點】

            語法: go run xxx.go   argv1 argv2  argv3  argv4 。。。

                        xxx.exe:  第 0 個參數。

                        argv1 :第 1 個參數。

                        argv2 :第 2 個參數。

                        argv3 :第 3 個參數。

                        argv4 :第 4 個參數。

            使用: list := os.Args  提取所有命令行參數。

獲取文件屬性函數:

            os.stat(文件訪問絕對路徑) ——> fileInfo 介面

            fileInfo 包含 兩個介面。

                        Name() 獲取文件名。 不帶訪問路徑

                        Size() 獲取文件大小。

網路文件傳輸 —— 發送端(客戶端)

            1.  獲取命令行參數,得到文件名(帶路徑)filePath list := os.Args

            2.  使用 os.stat() 獲取 文件名(不帶路徑)fileName

            3.  創建 用於數據傳輸的 socket  net.Dial("tcp", 「伺服器IP+port」) —— conn

            4.  發送文件名(不帶路徑)  給接收端, conn.write()

            5.  讀取 接收端回發「ok」,判斷無誤。封裝函數 sendFile(filePath, conn) 發送文件內容

            6.  實現 sendFile(filePath,  conn)

                        1) 只讀打開文件 os.Open(filePath)

                                    for {

                                    2) 從文件中讀數據  f.Read(buf)

                                    3) 將讀到的數據寫到socket中  conn.write(buf[:n])

                                    4)判斷讀取文件的 結尾。 io.EOF. 跳出循環

                                    }

網路文件傳輸 —— 接收端(伺服器)

            1. 創建用於監聽的 socket net.Listen() —— listener

            2. 藉助listener 創建用於 通信的 socket listener.Accpet()  —— conn

            3. 讀取 conn.read() 發送端的 文件名, 保存至本地。

            4. 回發 「ok」應答 發送端。

            5. 封裝函數,接收文件內容 recvFile(文件路徑)

                        1) f = os.Create(帶有路徑的文件名)

                        for {

                        2)從 socket中讀取發送端發送的 文件內容 。 conn.read(buf)

                        3)  將讀到的數據 保存至本地文件 f.Write(buf[:n])

                        4)  判斷 讀取conn 結束, 代表文件傳輸完成。 n == 0  break

                        }

            

㈨ linux下udp實現文件的傳輸,盡量詳細點 思路我知道 就是不知道怎麼把文件名給傳過去

傳文件最好用個TCP。UDP會丟包的

////////////////////////////////////
//客戶端代碼
///////////////////////////////////

//本文件是客戶機的代碼
#include <netinet/in.h> // for sockaddr_in
#include <sys/types.h> // for socket
#include <sys/socket.h> // for socket
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <string.h> // for bzero
#include <time.h> //for time_t and time
#include <arpa/inet.h>

#define HELLO_WORLD_SERVER_PORT 7754
#define BUFFER_SIZE 1024

int main(int argc, char **argv)
{
if (argc != 2)
{
printf("Usage: ./%s ServerIPAddress\n",argv[0]);
exit(1);
}

//time_t now;
FILE *stream;

//設置一個socket地址結構client_addr,代表客戶機internet地址, 埠
struct sockaddr_in client_addr;
bzero(&client_addr,sizeof(client_addr)); //把一段內存區的內容全部設置為0
client_addr.sin_family = AF_INET; //internet協議族
client_addr.sin_addr.s_addr = htons(INADDR_ANY);//INADDR_ANY表示自動獲取本機地址
client_addr.sin_port = htons(0); //0表示讓系統自動分配一個空閑埠
//創建用於internet的流協議(TCP)socket,用client_socket代表客戶機socket
int client_socket = socket(AF_INET,SOCK_STREAM,0);
if( client_socket < 0)
{
printf("Create Socket Failed!\n");
exit(1);
}
//把客戶機的socket和客戶機的socket地址結構聯系起來
if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr)))
{
printf("Client Bind Port Failed!\n");
exit(1);
}

//設置一個socket地址結構server_addr,代表伺服器的internet地址, 埠
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
if(inet_aton(argv[1],&server_addr.sin_addr) == 0) //伺服器的IP地址來自程序的參數
{
printf("Server IP Address Error!\n");
exit(1);
}
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
socklen_t server_addr_length = sizeof(server_addr);
//向伺服器發起連接,連接成功後client_socket代表了客戶機和伺服器的一個socket連接
if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0)
{
printf("Can Not Connect To %s!\n",argv[1]);
exit(1);
}

char buffer[BUFFER_SIZE];
bzero(buffer,BUFFER_SIZE);

//從伺服器接收數據到buffer中
int length = recv(client_socket,buffer,BUFFER_SIZE,0);

if(length < 0)
{
printf("Recieve Data From Server %s Failed!\n", argv[1]);
exit(1);
}

printf("\n%s\n",buffer);

bzero(buffer,BUFFER_SIZE);

bzero(buffer,BUFFER_SIZE);
strcpy(buffer,"Hello, World! From Client\n");
//向伺服器發送buffer中的數據
send(client_socket,buffer,BUFFER_SIZE,0);

if((stream = fopen("data","w+t"))==NULL)
{
printf("The file 'data' was not opened! \n");
}

else
bzero(buffer,BUFFER_SIZE);
length = 0;
while( length = recv(client_socket,buffer,BUFFER_SIZE,0))
{
if(length < 0)
{
printf("Recieve Data From Server %s Failed!\n", argv[1]);
break;
}

int write_length = fwrite(buffer,sizeof(char),length,stream);
if (write_length<length)
{
printf("File is Write Failed\n");
break;
}
bzero(buffer,BUFFER_SIZE);
}
printf("Recieve File From Server[%s] Finished\n", argv[1]);

//關閉 文件
fclose(stream);

//關閉socket
close(client_socket);
return 0;
}

////////////////////////////////////
//伺服器代碼
///////////////////////////////////
//本文件是伺服器的代碼
#include <netinet/in.h> // for sockaddr_in
#include <sys/types.h> // for socket
#include <sys/socket.h> // for socket
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <string.h> // for bzero
#include <time.h> //for time_t and time

#define HELLO_WORLD_SERVER_PORT 7754
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024

int main(int argc, char **argv)
{
//設置一個socket地址結構server_addr,代表伺服器internet地址, 埠
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr)); //把一段內存區的內容全部設置為0
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
// time_t now;
FILE *stream;

//創建用於internet的流協議(TCP)socket,用server_socket代表伺服器socket
int server_socket = socket(AF_INET,SOCK_STREAM,0);
if( server_socket < 0)
{
printf("Create Socket Failed!");
exit(1);
}

//把socket和socket地址結構聯系起來
if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))
{
printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);
exit(1);
}

//server_socket用於監聽
if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) )
{
printf("Server Listen Failed!");
exit(1);
}

while (1) //伺服器端要一直運行
{

struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);

int new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&length);
if ( new_server_socket < 0)
{
printf("Server Accept Failed!\n");
break;
}

char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);

strcpy(buffer,"Hello,World! 從伺服器來!");
strcat(buffer,"\n"); //C語言字元串連接

send(new_server_socket,buffer,BUFFER_SIZE,0);

bzero(buffer,BUFFER_SIZE);
//接收客戶端發送來的信息到buffer中
length = recv(new_server_socket,buffer,BUFFER_SIZE,0);

if (length < 0)
{
printf("Server Recieve Data Failed!\n");
exit(1);
}
printf("\n%s",buffer);

if((stream = fopen("/home/administrator/110405A000.jpg","r"))==NULL)
{
printf("The file 'data1' was not opened! \n");
exit(1);
}
else

printf("The file 'filename' was opened! \n");
bzero(buffer,BUFFER_SIZE);

int lengsize = 0;
while((lengsize = fread(buffer,1,1024,stream)) > 0)
{

printf("lengsize = %d\n",lengsize);

if(send(new_server_socket,buffer,lengsize,0)<0)
{
printf("Send File is Failed\n");
break;
}

bzero(buffer, BUFFER_SIZE);

}
if(fclose(stream))
printf("The file 'data' was not closed! \n");
exit(1);

//關閉與客戶端的連接
close(new_server_socket);
}
//關閉監聽用的socket
close(server_socket);
return 0;
}

㈩ java UDP 傳輸文件

//Send
DatagramSocket ds = new DatagramSocket(5555, InetAddress
.getByName("10.0.0.1"));
InputStream in = new FileInputStream(new File("a.txt"));
byte[] b = new byte[10240];
int c = in.read(b);
in.close();
DatagramPacket dp = new DatagramPacket(b, c);
ds.send(dp);

//Receive
DatagramSocket ds2 = new DatagramSocket(5555);
DatagramPacket dp2 = new DatagramPacket(b,b.length);
ds2.receive(dp2);
OutputStream out=new FileOutputStream(new File("out.txt"));
out.write(dp2.getData());
out.close();

熱點內容
華為安卓如何更新鴻蒙 發布:2025-05-15 08:18:52 瀏覽:372
工商密碼器是什麼 發布:2025-05-15 08:18:50 瀏覽:750
c語言自考 發布:2025-05-15 07:52:42 瀏覽:501
壓縮的玉 發布:2025-05-15 07:51:22 瀏覽:790
android的控制項 發布:2025-05-15 07:50:36 瀏覽:553
南崗法院伺服器ip地址 發布:2025-05-15 07:46:02 瀏覽:288
實況如何退出賬號安卓 發布:2025-05-15 07:45:56 瀏覽:919
深入編譯器 發布:2025-05-15 07:41:35 瀏覽:879
電信手機號服務密碼怎麼查 發布:2025-05-15 07:40:10 瀏覽:614
python全局變數文件 發布:2025-05-15 07:35:06 瀏覽:955