C语言UDP网络编程详解(UDP网络编程)

http://www.itjxue.com  2023-02-02 12:26  来源:未知  点击次数: 

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));

(责任编辑:IT教学网)

更多

推荐软件水平考试文章