C语言UDP网络编程详解(UDP网络编程)
C语言UDP协议
简单的学习代码,仅供参考:
server.c
#include?stdlib.h
#include?stdio.h
#include?string.h
#include?netdb.h
#include?sys/socket.h
#include?arpa/inet.h
#define?SERVICE_PORT 8080
#define?BUFSIZE?2048
#define?HEAD?4
int?main(int?argc,?char?**argv)
{
struct?sockaddr_in?myaddr; /*?our?address?*/
struct?sockaddr_in?remaddr; /*?remote?address?*/
socklen_t?addrlen?=?sizeof(remaddr); /*?length?of?addresses?*/
int?recvlen; /*?#?bytes?received?*/
int?fd; ????/*?our?socket?*/
int?msgcnt?=?0; /*?count?#?of?messages?we?received?*/
unsigned?char?buf[BUFSIZE]="ret_"; /*?receive?buffer?*/
/*?create?a?UDP?socket?*/
if?((fd?=?socket(AF_INET,?SOCK_DGRAM,?0))??0)?{
perror("cannot?create?socket\n");
return?0;
}
/*?bind?the?socket?to?any?valid?IP?address?and?a?specific?port?*/
memset((char?*)myaddr,?0,?sizeof(myaddr));
myaddr.sin_family?=?AF_INET;
myaddr.sin_addr.s_addr?=?htonl(INADDR_ANY);
myaddr.sin_port?=?htons(SERVICE_PORT);
if?(bind(fd,?(struct?sockaddr?*)myaddr,?sizeof(myaddr))??0)?{
perror("bind?failed");
return?0;
}
/*?now?loop,?receiving?data?and?printing?what?we?received?*/
for?(;;)?
{
printf("waiting?on?port?%d\n",?SERVICE_PORT);
recvlen?=?recvfrom(fd,?buf+HEAD,?BUFSIZE,?0,?(struct?sockaddr?*)remaddr,?addrlen);
if?(recvlen??0)?
{
buf[HEAD+recvlen]?=?0;
printf("received?message:?\"%s\"?(%d?bytes)\n",?buf+HEAD,?recvlen);
}
else
{
printf("uh?oh?-?something?went?wrong!\n");
}
printf("sending?response?\"%s\"\n",?buf);
if?(sendto(fd,?buf,?strlen(buf),?0,?(struct?sockaddr?*)remaddr,?addrlen)??0)
{
perror("sendto");
}
}
close(fd);
return?0;
}
client.c
#include?stdlib.h
#include?stdio.h
#include?string.h
#include?netdb.h
#include?sys/socket.h
#define?SERVICE_PORT 8080
#define?BUFLEN?2048
int?main(?int?argc,char*?argv[]?)
{
struct?sockaddr_in?myaddr,?remaddr;
int?fd,?i,?slen=sizeof(remaddr);
char?sendbuf[BUFLEN]="hello"; /*?message?buffer?*/
char?readbuf[BUFLEN]={0};
int?recvlen; /*?#?bytes?in?acknowledgement?message?*/
char?*server?=?"127.0.0.1"; /*?change?this?to?use?a?different?server?*/
/*?create?a?socket?*/
if?((fd=socket(AF_INET,?SOCK_DGRAM,?0))==-1)
{
printf("socket?created\n");
}
/*?bind?it?to?all?local?addresses?and?pick?any?port?number?*/
memset((char?*)myaddr,?0,?sizeof(myaddr));
myaddr.sin_family?=?AF_INET;
myaddr.sin_addr.s_addr?=?htonl(INADDR_ANY);
myaddr.sin_port?=?htons(0);
if?(bind(fd,?(struct?sockaddr?*)myaddr,?sizeof(myaddr))??0)?
{
perror("bind?failed");
return?0;
}???????
memset((char?*)?remaddr,?0,?sizeof(remaddr));
remaddr.sin_family?=?AF_INET;
remaddr.sin_port?=?htons(SERVICE_PORT);
if?(inet_aton(server,?remaddr.sin_addr)==0)?
{
fprintf(stderr,?"inet_aton()?failed\n");
exit(1);
}
printf("Sending?packet?%d?to?%s?port?%d\n",?i,?server,?SERVICE_PORT);
if?(sendto(fd,?sendbuf,?strlen(sendbuf),?0,?(struct?sockaddr?*)remaddr,?slen)==-1)
{
perror("sendto");
exit(1);
}
/*?now?receive?an?acknowledgement?from?the?server?*/
recvlen?=?recvfrom(fd,?readbuf,?BUFLEN,?0,?(struct?sockaddr?*)remaddr,?slen);
if?(?recvlen?=?0?)?
{
readbuf[recvlen]?=?0; /*?expect?a?printable?string?-?terminate?it?*/
printf("received?message:?\"%s\"\n",?readbuf);
}
close(fd);
return?0;
}
如果需要整个工程,可以联系我。
c#网络编程UDP例子
using?System;?
using?System.Net;?
using?System.Net.Sockets;?
using?System.Text;?
using?System.Threading;?
using?System.Windows.Forms;?
?namespace?UDPClient?
{?
????public?partial?class?frmUdp?:?Form?
????{?
????????private?UdpClient?sendUdpClient;?
????????private?UdpClient?receiveUpdClient;?
????????public?frmUdp()?
????????{?
????????????InitializeComponent();?
????????????IPAddress[]?ips?=?Dns.GetHostAddresses("");?
????????????tbxlocalip.Text?=?ips[2].ToString();?
????????????int?port?=?51883;?
????????????tbxlocalPort.Text?=?port.ToString();?
????????????tbxSendtoIp.Text?=?ips[2].ToString();?
????????????tbxSendtoport.Text?=?port.ToString();?
????????}?
?
????????//?接受消息?
????????private?void?btnReceive_Click(object?sender,?EventArgs?e)?
????????{?
????????????//?创建接收套接字?
????????????IPAddress?localIp?=?IPAddress.Parse(tbxlocalip.Text);?
????????????IPEndPoint?localIpEndPoint?=?new?IPEndPoint(localIp,?int.Parse(tbxlocalPort.Text));?
????????????receiveUpdClient?=?new?UdpClient(localIpEndPoint);?
?
?
????????????Thread?receiveThread?=?new?Thread(ReceiveMessage);?
????????????receiveThread.Start();?
????????}?
?
????????//?接收消息方法?
????????private?void?ReceiveMessage()?
????????{?
????????????IPEndPoint?remoteIpEndPoint?=?new?IPEndPoint(IPAddress.Any,?0);?
????????????while?(true)?
????????????{?
????????????????try?
????????????????{?
????????????????????//?关闭receiveUdpClient时此时会产生异常?
????????????????????byte[]?receiveBytes?=?receiveUpdClient.Receive(ref?remoteIpEndPoint);?
?
????????????????????string?message?=?Encoding.Unicode.GetString(receiveBytes);?
?
????????????????????//?显示消息内容?
????????????????????ShowMessageforView(lstbxMessageView,?string.Format("{0}[{1}]",?remoteIpEndPoint,?message));?
????????????????}?
????????????????catch?
????????????????{?
????????????????????break;?
????????????????}?
????????????}?
????????}?
?
????????//?利用委托回调机制实现界面上消息内容显示?
????????delegate?void?ShowMessageforViewCallBack(ListBox?listbox,?string?text);?
????????private?void?ShowMessageforView(ListBox?listbox,?string?text)?
????????{?
????????????if?(listbox.InvokeRequired)?
????????????{?
????????????????ShowMessageforViewCallBack?showMessageforViewCallback?=?ShowMessageforView;?
????????????????listbox.Invoke(showMessageforViewCallback,?new?object[]?{?listbox,?text?});?
????????????}?
????????????else?
????????????{?
????????????????lstbxMessageView.Items.Add(text);?
????????????????lstbxMessageView.SelectedIndex?=?lstbxMessageView.Items.Count?-?1;?
????????????????lstbxMessageView.ClearSelected();?
????????????}?
????????}?
????????private?void?btnSend_Click(object?sender,?EventArgs?e)?
????????{?
????????????if?(tbxMessageSend.Text?==?string.Empty)?
????????????{?
????????????????MessageBox.Show("发送内容不能为空","提示");?
????????????????return;?
????????????}?
?
????????????//?选择发送模式?
????????????if?(chkbxAnonymous.Checked?==?true)?
????????????{?
????????????????//?匿名模式(套接字绑定的端口由系统随机分配)?
????????????????sendUdpClient?=?new?UdpClient(0);?
????????????}?
????????????else?
????????????{?
????????????????//?实名模式(套接字绑定到本地指定的端口)?
????????????????IPAddress?localIp?=?IPAddress.Parse(tbxlocalip.Text);?
????????????????IPEndPoint?localIpEndPoint?=?new?IPEndPoint(localIp,?int.Parse(tbxlocalPort.Text));?
????????????????sendUdpClient?=?new?UdpClient(localIpEndPoint);?
????????????}?
?
????????????Thread?sendThread?=?new?Thread(SendMessage);?
????????????sendThread.Start(tbxMessageSend.Text);?
????????}?
?
????????//?发送消息方法?
????????private?void?SendMessage(object?obj)?
????????{?
????????????string?message?=?(string)obj;?
????????????byte[]?sendbytes?=?Encoding.Unicode.GetBytes(message);?
????????????IPAddress?remoteIp?=?IPAddress.Parse(tbxSendtoIp.Text);?
????????????IPEndPoint?remoteIpEndPoint?=?new?IPEndPoint(remoteIp,?int.Parse(tbxSendtoport.Text));?
????????????sendUdpClient.Send(sendbytes,?sendbytes.Length,?remoteIpEndPoint);?
???????????
????????????sendUdpClient.Close();?
????????????
????????????//?清空发送消息框?
????????????ResetMessageText(tbxMessageSend);?
????????}?
?
????????//?采用了回调机制?
????????//?使用委托实现跨线程界面的操作方式?
????????delegate?void?ResetMessageCallback(TextBox?textbox);?
????????private?void?ResetMessageText(TextBox?textbox)?
????????{?
????????????//?Control.InvokeRequired属性代表?
????????????//?如果空间的处理与调用线程在不同线程上创建的,则为true,否则为false?
????????????if?(textbox.InvokeRequired)?
????????????{?
????????????????ResetMessageCallback?resetMessagecallback?=?ResetMessageText;?
????????????????textbox.Invoke(resetMessagecallback,?new?object[]?{?textbox?});?
????????????}?
????????????else?
????????????{?
????????????????textbox.Clear();?
????????????????textbox.Focus();?
????????????}?
????????}?
?
????????//?停止接收?
????????private?void?btnStop_Click(object?sender,?EventArgs?e)?
????????{?
????????????receiveUpdClient.Close();?
????????}?
?
????????//?清空接受消息框?
????????private?void?btnClear_Click(object?sender,?EventArgs?e)?
????????{?
????????????this.lstbxMessageView.Items.Clear();?
????????}?
????}?
}
C语言 UDP socket 简单客户端 编程,急
提一下,你那个地址不好用,换成了127.0.0.1,端口可以用,完全按照要求写的,编译没错误,调试通过:
gcc server.c -o server
gcc client.c -o client
打开2个控制台:一个运行 ./server 另一个运行 ./client
server.c:
========================================
#include stdio.h
#include stdlib.h
#include string.h
#include sys/types.h
#include sys/socket.h
#include arpa/inet.h
#include errno.h
#define BUFFERSIZE 1024
typedef struct sockaddr SA;
int main(void)
{
char buf[BUFFERSIZE];
struct sockaddr_in addr_s;
struct sockaddr_in addr_c;
int sockfd;
socklen_t length;
int i;
if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1)
{
perror("socket fail");
return -1;
}
memset(addr_s,0,sizeof(addr_s));
addr_s.sin_family = AF_INET;
addr_s.sin_addr.s_addr = inet_addr("127.0.0.1");
addr_s.sin_port = htons(31180);
if(bind(sockfd,(SA *)addr_s,sizeof(addr_s)) == -1)
{
perror("bind fail");
return -1;
}
length = sizeof(addr_c);
memset(buf,'\0',sizeof(buf));
if(recvfrom(sockfd,buf,sizeof(buf),0
,(SA *)addr_c,length) == -1)
{
perror("recvfrom fail");
}
printf("recvfrom client:%s\n",buf);
sendto(sockfd,buf,sizeof(buf),0,(SA *)addr_c,sizeof(addr_c));
close(sockfd);
}
====================================
client.c:
====================================
#include stdio.h
#include stdlib.h
#include string.h
#include sys/types.h
#include sys/socket.h
#include arpa/inet.h
#include errno.h
#define BUFFERSIZE 1024
typedef struct sockaddr SA;
int main(void)
{
int sockfd;
char buf[BUFFERSIZE];
struct sockaddr_in addr_s;
if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1)
{
perror("socket fail");
return -1;
}
memset(addr_s,0,sizeof(addr_s));
addr_s.sin_family = AF_INET;
addr_s.sin_addr.s_addr = inet_addr("127.0.0.1");
addr_s.sin_port = htons(31180);
memset(buf,'\0',sizeof(buf));
sprintf(buf,"abcde");
if(sendto(sockfd,buf,sizeof(buf)
,0,(SA *)addr_s,sizeof(addr_s)) 0)
{
perror("sendto fail");
}
memset(buf,'\0',sizeof(buf));
recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);
printf("recvfrom server:%s\n",buf);
close(sockfd);
}
实现UDP协议传输的C语言程序。如被采纳,可追加悬赏,盼高手指教,不胜感激!!!
原型:
int WINAPI icePub_UdpSendAndReceive(char *sendBuffer,int bufferLen,char *strIP,int port,char *receiveBuffer,int timeoutSeconds,int retryCounts)
输入:sendBuffer 发送的数据
bufferLen sendBuffer的长度
strIP 服务端地址
port 端口
timeoutSeconds 超时时间,秒
retryCounts 接收失败重发次数
输出:receiveBuffer 接收的数据
返回码:接收数据的长度
char buff[1024],buff2[1024*10];
int receiveLen;
strcpy(buff,"tag:01\r\ncommand:reboot\r\ndata:none\r\n");
typedef int (WINAPI ICEPUB_UDPSENDANDRECEIVE)(char *sendBuffer,int bufferLen,char *strIP,int port,char *receiveBuffer,int timeoutSeconds,int retryCounts);
ICEPUB_UDPSENDANDRECEIVE *icePub_UdpSendAndReceive = 0;
HINSTANCE hDLLDrv = LoadLibrary("icePubDll.dll");
if(hDLLDrv)
icePub_UdpSendAndReceive=(ICEPUB_UDPSENDANDRECEIVE *)GetProcAddress(hDLLDrv,"icePub_UdpSendAndReceive");
if(icePub_UdpSendAndReceive)
receiveLen=icePub_UdpSendAndReceive(buff,strlen(buff),"192.168.1.111",6000,buff2,15,1);
if(hDLLDrv)
FreeLibrary(hDLLDrv);
AfxMessageBox(buff2);
请教用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
以下是程序代码:
#includestdio.h
#includestdlib.h
#includestring.h
#includemath.h
#ifdef?_MSC_VER
????#includewinsock2.h
????#includewindows.h
????#pragma?comment(lib,?"ws2_32.lib")
#else
????#includepthread.h
????#includeunistd.h
????#includesignal.h
????#includesys/socket.h
????#includearpa/inet.h
#endif
//?存放发送接收字符数组大小
#define?SIZEA?65501
//?每次发送接收字节数
#define?SIZEB?65500
typedef?struct?sockaddr_in?SockAddrIn;
SockAddrIn?serverAddr,?remoteAddr,?clientAddr;
//?端口号
int?iServerPort,?iClientPort;
//?新建?socket?信息
int?iUDP;
//?字符串转整型
int?strToInt(char*?acStr)
{
????int?i,?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;?iiSize;?i++)
????????iNum?+=?(int)pow(10,?iSize?-?i?-?1)?*?(acStr[i]?-?48);
????if(acStr[0]?==?'-')
????????iNum?=?-?iNum;
????return?iNum;
}
//?整型转字符串
void?intToStr(int?iInt,?char*?acStr)
{
????int?iIndex?=?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;?iiSize;?i++)
????{
????????iNum?=?pow(10,?iSize?-?i?-?1);
????????iBit?=?iInt/iNum;
????????iInt?-=?iNum*iBit;
????????acStr[i?+?iIndex]?=?iBit?+?48;
????}
????if(iSize?!=?0)
????????acStr[iSize?+?iIndex]?=?'\0';
????else
????{
????????acStr[0]?=?'0';
????????acStr[1]?=?'\0';
????}
}
void?sleepUDP(int?iSleep)
{
#ifdef?_MSC_VER
????Sleep(iSleep);
#else
????usleep(iSleep*1000);
#endif
}
void?openUDP(char*?acIpAddr)
{
#ifdef?_MSC_VER
????//?Winsows?启用?socket
????WSADATA?wsadata;
????if(WSAStartup(MAKEWORD(1,?1),?wsadata)?==?SOCKET_ERROR)
????{
????????printf("启用?socket?失败\n");
????????exit(0);
????}
#endif
????//?新建?socket
????if((iUDP?=?socket(AF_INET,?SOCK_DGRAM,?IPPROTO_UDP))?==?-1)
????{
????????printf("新建?socket?失败\n");
????????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,?(struct?sockaddr*)serverAddr,?sizeof(serverAddr))?==?-1)
????{
????????printf("绑定端口失败\n");
????????exit(0);
????}
}
void?closeUDP(void)
{
#ifdef?_MSC_VER
????//?Winsows?关闭?socket
????closesocket(iUDP);
????WSACleanup();
#endif
}
//?要发送的字符串
char?acSendStr[SIZEA];
//?接收到的字符串
char?acRecvStr[SIZEA];
//?请求信息
char?acReq[SIZEA];
//?文件名字符串
char?acFileName[SIZEA];
//?文件字节数字符串
char?acFileSize[SIZEA];
int?iSize,?iNameSize;
//?接收文件名
#ifdef?_MSC_VER
DWORD?WINAPI?recvName(LPVOID?p)
#else
void*?recvName(void*?arg)
#endif
{
????int?iAddrSize?=?sizeof(remoteAddr);
????acReq[0]?=?'n';?acReq[1]?=?'a';?acReq[2]?=?'m';?acReq[3]?=?'e';?acReq[4]?=?'\0';
????acRecvStr[0]?=?'\0';
????printf("%s\n",?"正在发送请求信息!");
????//?发送请求信息
????sendto(iUDP,?acReq,?strlen(acReq),?0,?(struct?sockaddr*)clientAddr,?sizeof(clientAddr));
????//?每次发送请求信息后等待一段时间
????sleepUDP(10);
????//?接收文件名
????iSize?=?recvfrom(iUDP,?acRecvStr,?SIZEB,?0,?(struct?sockaddr*)remoteAddr,?iAddrSize);
????return?0;
}
//?接收文件
void?recvFile(char*?acDirName,?char*?acIpAddr)
{
????FILE*?pFile?=?NULL;
????int?i,?iFileSize,?iRecvNum,?iAddrSize?=?sizeof(remoteAddr);
????//?路径文件名
????char?acDirAndFileName[SIZEA];
????openUDP(acIpAddr);
????//?接收文件名
????for(;;)
????{
????????//?创建线程
????????#ifdef?_MSC_VER
????????????HANDLE?hThread;
????????????DWORD?threadId;
????????????hThread?=?CreateThread(NULL,?0,?recvName,?0,?0,?threadId);
????????????//?每次发送后等待一段时间
????????????sleepUDP(1000);
????????????//?强制终止线程
????????????TerminateThread(hThread,?0);
????????#else
????????????pthread_t?thread;
????????????void*?thread_arg?=?(pthread_t)0;
????????????pthread_create(thread,?NULL,?recvName,?(void*)thread_arg);
????????????//?每次发送后等待一段时间
????????????sleepUDP(1000);
????????????//?强制终止线程
????????????pthread_cancel(thread);
????????#endif
????????if(acRecvStr[0]?!=?'\0')
????????{
????????????acRecvStr[iSize]?=?'\0';
????????????printf("文件名为:%s\n",?acRecvStr);
????????????break;
????????}
????}
????acDirAndFileName[0]?=?'\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]?=?'\0';
????//?接收文件字节数
????for(;;)
????{
????????//?发送请求信息
????????sendto(iUDP,?acReq,?strlen(acReq)?+?1,?0,?(struct?sockaddr*)clientAddr,?sizeof(clientAddr));
????????//?每次发送请求信息后等待一段时间
????????sleepUDP(10);
????????//?接收文件字节数
????????acRecvStr[0]?=?'\0';
????????iSize?=?recvfrom(iUDP,?acRecvStr,?SIZEB,?0,?(struct?sockaddr*)remoteAddr,?iAddrSize);
????????if(acRecvStr[0]?!=?'\0')
????????{
????????????acRecvStr[iSize]?=?'\0';
????????????iFileSize?=?strToInt(acRecvStr);
????????????printf("文件字节数为:%d\n",?iFileSize);
????????????break;
????????}
????}
????//?以追加方式写入文件
????pFile?=?fopen(acDirAndFileName,?"ab");
????//?文件分几次接收
????iRecvNum?=?iFileSize/SIZEB;
????//?接收文件
????for(i=0;?iiRecvNum;?i++)
????{
????????intToStr(i,?acReq);
????????for(;;)
????????{
????????????//?发送请求信息
????????????sendto(iUDP,?acReq,?strlen(acReq)?+?1,?0,?(struct?sockaddr*)clientAddr,?sizeof(clientAddr));
????????????printf("%s\t正在接收文件的第?%d?段\n",?acReq,?i);
????????????//?每次发送请求信息后等待一段时间
????????????sleepUDP(10);
????????????//?接收一段文件
????????????iSize?=?recvfrom(iUDP,?acRecvStr,?SIZEB,?0,?(struct?sockaddr*)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]?=?'\0';
????????for(;;)
????????{
????????????//?发送请求信息
????????????sendto(iUDP,?acReq,?strlen(acReq)?+?1,?0,?(struct?sockaddr*)clientAddr,?sizeof(clientAddr));
????????????//?每次发送请求信息后等待一段时间
????????????sleepUDP(10);
????????????//?接收文件剩余字节
????????????if(recvfrom(iUDP,?acRecvStr,?iSize,?0,?(struct?sockaddr*)remoteAddr,?iAddrSize)?==?iSize)
????????????{
????????????????//?以追加方式写入文件
????????????????fwrite(acRecvStr,?sizeof(char),?iSize,?pFile);
????????????????break;
????????????}
????????}
????}
????printf("%s\n",?"文件接收完毕!");
????//?关闭文件
????fclose(pFile);
????//?关闭连接
????closeUDP();
}
//?发送文件名
#ifdef?_MSC_VER
DWORD?WINAPI?sendName(LPVOID?p)
#else
void*?sendName(void*?arg)
#endif
{
????int?iAddrSize?=?sizeof(remoteAddr);
????acRecvStr[0]?=?'\0';
????//?接收请求
????printf("%s\n",?"正在接收请求信息!");
????recvfrom(iUDP,?acRecvStr,?5,?0,?(struct?sockaddr*)remoteAddr,?iAddrSize);
????//?每次接收请求信息后等待一段时间
????sleepUDP(10);
????//?如果请求信息正确发送文件名
????if(acRecvStr[0]?==?'n'??acRecvStr[1]?==?'a'??acRecvStr[2]?==?'m'??acRecvStr[3]?==?'e'??acRecvStr[4]?==?'\0')
????????sendto(iUDP,?acFileName,?iNameSize,?0,?(struct?sockaddr*)clientAddr,?sizeof(clientAddr));
????return?0;
}
//?发送文件
void?sendFile(char*?acDirAndFileName,?char*?acIpAddr)
{
????int?i,?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\n",?acDirAndFileName);
????//?获取文件名长度
????iSize?=?strlen(acDirAndFileName);
????for(i=iSize-1,?iNameSize=0;?i=0;?i--,iNameSize++)
????????if(acDirAndFileName[i]?==?'\\'?||?acDirAndFileName[i]?==?'/')
????????????break;
????//printf("%d\n",?iNameSize);
????//?截取文件名
????for(i=0;?iiNameSize;?i++)
????????acFileName[i]?=?acDirAndFileName[iSize?-?iNameSize?+?i];
????acFileName[iNameSize]?=?'\0';
????//printf("%s\n",?acFileName);
????openUDP(acIpAddr);
????//?发送文件名
????for(;;)
????{
????//?创建线程
????#ifdef?_MSC_VER
????????HANDLE?hThread;
????????DWORD?threadId;
????????hThread?=?CreateThread(NULL,?0,?sendName,?0,?0,?threadId);
????????//?每次接收请求信息后等待一段时间
????????sleepUDP(1000);
????????//?强制终止线程
????????TerminateThread(hThread,?0);
????#else
????????pthread_t?thread;
????????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]?==?'\0')
????????????break;
????}
????//?发送文件字节数
????for(;;)
????{
????????acRecvStr[0]?=?'\0';
????????//?接收请求
????????recvfrom(iUDP,?acRecvStr,?5,?0,?(struct?sockaddr*)remoteAddr,?iAddrSize);
????????//?每次接收请求信息后等待一段时间
????????sleepUDP(10);
????????//?如果请求信息正确
????????if(acRecvStr[0]?==?'s'??acRecvStr[1]?==?'i'??acRecvStr[2]?==?'z'??acRecvStr[3]?==?'e'??acRecvStr[4]?==?'\0')
????????{
????????????//?发送文件字节数
????????????sendto(iUDP,?acFileSize,?strlen(acFileSize),?0,?(struct?sockaddr*)clientAddr,?sizeof(clientAddr));
????????????break;
????????}
????}
????iSendNum?=?iFileSize/SIZEB;
????//?发送文件
????if(iSendNum??0)
????{
????????for(i=0;;i++)
????????{
????????????acRecvStr[0]?=?'\0';
????????????//?接收请求
????????????recvfrom(iUDP,?acRecvStr,?SIZEB,?0,?(struct?sockaddr*)remoteAddr,?iAddrSize);
????????????printf("%s\t正在发送文件的第?%d?段\n",?acRecvStr,?i);
????????????//?每次接收请求信息后等待一段时间
????????????sleepUDP(10);
????????????fseek(pFile,?strToInt(acRecvStr)*SIZEB,?SEEK_SET);
????????????fread(acSendStr,?1,?SIZEB,?pFile);
????????????//printf("%s\n",?acSendStr);
????????????//?发送一段文件
????????????sendto(iUDP,?acSendStr,?SIZEB,?0,?(struct?sockaddr*)clientAddr,?sizeof(clientAddr));
????????????if(strToInt(acRecvStr)?=?iSendNum?-?1)
????????????????break;
????????}
????}
????//?发送文件剩余字节
????iSize?=?iFileSize%SIZEB;
????if(iSize??0)
????{
????????for(;;)
????????{
????????????acRecvStr[0]?=?'\0';
????????????//?接收请求
????????????recvfrom(iUDP,?acRecvStr,?5,?0,?(struct?sockaddr*)remoteAddr,?iAddrSize);
????????????//?每次接收请求信息后等待一段时间
????????????sleepUDP(10);
????????????//?如果请求信息正确
????????????if(acRecvStr[0]?==?'l'??acRecvStr[1]?==?'a'??acRecvStr[2]?==?'s'??acRecvStr[3]?==?'t'??acRecvStr[4]?==?'\0')
????????????{
????????????????fseek(pFile,?iSendNum*SIZEB,?SEEK_SET);
????????????????fread(acSendStr,?1,?iSize,?pFile);
????????????????//printf("%s\n",?acSendStr);
????????????????//?发送文件剩余字节
????????????????sendto(iUDP,?acSendStr,?iSize,?0,?(struct?sockaddr*)clientAddr,?sizeof(clientAddr));
????????????????break;
????????????}
????????}
????}
????printf("%s\n",?"文件发送完毕!");
????//?关闭连接
????closeUDP();
}
int?main(void)
{
????char?acDirName[SIZEA];
????char?acDirAndFileName[SIZEA];
????char?acIpAddr[15];
????int?i,?iOption?=?0,?iSize?=?0;
????FILE*?pFile?=?NULL;
????char?cLast?=?'\\';
option:
????printf("%s\n",?"****************************************************\n本程序包括服务器端和客户端,既可以发送文件又可以接收文件。\n支持无线?WiFi,支持?USB?收发器,但仅支持局域网内传送文件。\n如果要在?Windows?和?Linux?之间传送文件,文件名不能出现中文。\n如果要在同一台机器上测试需要同时打开两个程序。\n****************************************************");
????printf("%s\n",?"请输入选项,1.发送文件、2.接收文件。");
????scanf("%d",?iOption);
????//?发送文件
????if(iOption?==?1)
????{
????????iServerPort?=?1025;
????????iClientPort?=?1024;
????fileName:
????????printf("%s\n",?"请输入需要发送的路径文件名。\nWindows?路径文件名格式:\t\tC:\\install.txt\nLinux?路径文件名格式:\t\t/home/install.txt");
????????scanf("%s",?acDirAndFileName);
????????pFile?=?fopen(acDirAndFileName,?"rb");
????????if(pFile?==?NULL)
????????{
????????????printf("%s\n",?"读取文件失败,请重新输入文件名。");
????????????goto?fileName;
????????}
????????//?关闭文件
????????fclose(pFile);
????????printf("%s\n",?"请输入接收文件方的?IP?地址,不能有空格。\n例如:\n192.168.1.104");
????????scanf("%s",?acIpAddr);
????????sendFile(acDirAndFileName,?acIpAddr);
????}
????//?接收文件
????else?if(iOption?==?2)
????{
????????iServerPort?=?1024;
????????iClientPort?=?1025;
????dirName:
????????printf("%s\n",?"请输入保存文件的路径名。\nWindows?路径名格式:\t\tC:\\img\\\nLinux?路径名格式:\t\t/home/");
????????scanf("%s",?acDirName);
????????iSize?=?strlen(acDirName);
????????//?检查是不是?Linux?路径名
????????for(i=0;?iiSize;?i++)
????????{
????????????if(acDirName[i]?==?'/')
????????????{
????????????????cLast?=?'/';
????????????????break;
????????????}
????????}
????????//?检查路径名最后一个字符是不是?\?或?/
????????if(acDirName[iSize?-?1]?!=?cLast)
????????{
????????????acDirName[iSize]?=?cLast;
????????????acDirName[iSize?+?1]?=?'\0';
????????}
????????acDirAndFileName[0]?=?'\0';
????????strcat(acDirAndFileName,?acDirName);
????????strcat(acDirAndFileName,?"a.txt");
????????//?试探保存一个无关紧要的文件
????????pFile?=?fopen(acDirAndFileName,?"w");
????????if(pFile?==?NULL)
????????{
????????????printf("%s\n",?"该路径无法创建文件,请重新输入路径名。");
????????????goto?dirName;
????????}
????????else
????????{
????????????//?关闭文件
????????????fclose(pFile);
????????????//?删除文件
????????????remove(acDirAndFileName);
????????}
????????printf("%s\n",?"请输入发送文件方的?IP?地址,不能有空格。\n例如:\n192.168.2.249");
????????scanf("%s",?acIpAddr);
????????recvFile(acDirName,?acIpAddr);
????}
????else
????{
????????printf("%s\n",?"没有这个选项,请重新输入。");
????????goto?option;
????}
????return?0;
}
求助,基于C语言的UDP通信问题发送、接收端口问题
bind一下就可以
int s = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in local= {0};
local.sin_family = AF_INET;
?local.sin_port = htons(60200);
inet_aton("192.168.3.100", (struct in_addr *)local.sin_addr.s_addr);//换成你的IP地址??
bind(s, (struct sockaddr *)local, sizeof(local));