C语言网络编程udp(C语言网络编程推荐书籍)
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);
}
c#udp源端口目的端口不同
在unity中使用UDP进行数据的交互,建立C/S模式,两个客户端和一个服务端。两个客户端使用不同的端口往服务端发送数据,服务端根据收到的数据进行处理和判断,控制服务端的显示。
说明:两个客户端连接的是Kinect V2,需要将检测到的人体的数据信息发送到服务端进行系统数据的整体显示。指定的消息协议是ClientID|index|PosLeft|Left_S|PosRight|Right_S|ACTION| ClientID|index|PosLeft|Left_S|PosRight|Right_S|ACTION| ...
这是客户端根据检测到人体的数量向服务端发送的数据格式。
服务端:使用两个线程用于接收两个客户端的数据,将收到的数据添加到Queue中。在需要显示数据的Update中从Queue中取出数据进行处理控制。
这里服务端的接收数据脚本直接上代码:
using UnityEngine;
using System.Collections;
//引入库
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections.Generic;
public class UdpHelpHandler : MonoBehaviour {
//以下默认都是私有的成员
Socket socket,socket2; //目标socket
EndPoint clientEnd; //客户端
IPEndPoint ipEnd,ipEnd2; //侦听端口
string recvStr,recvStr2; //接收的字符串
string sendStr; //发送的字符串
byte[] recvData=new byte[1024]; //接收的数据,必须为字节
byte[] recvData2=new byte[1024]; //接收的数据,必须为字节
byte[] sendData=new byte[1024]; //发送的数据,必须为字节
int recvLen,recvLen2; //接收的数据长度
Thread connectThread,connectThread2; //连接线程
int[] WaveCounts = new int[2];
int[] TPoseCounts = new int[2];
public Queuestring queueClient1 = new Queuestring();
public Queuestring queueClient2 = new Queuestring();
private System.Object thisLock = new System.Object ();
//初始化
public void InitSocket()
{
//定义侦听端口,侦听任何IP
ipEnd=new IPEndPoint(IPAddress.Any,2000);
//定义套接字类型,在主线程中定义
socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
//服务端需要绑定ip
try{
socket.Bind(ipEnd);
}
catch (System.Exception ex)
{
socket.Close ();
Debug.LogError(ex.Message + "\n" + ex.StackTrace);
}
//定义侦听端口,侦听任何IP
ipEnd2=new IPEndPoint(IPAddress.Any,3000);
//定义套接字类型,在主线程中定义
socket2=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
//服务端需要绑定ip
try{
socket2.Bind(ipEnd2);
}
catch (System.Exception ex)
{
socket2.Close ();
Debug.LogError(ex.Message + "\n" + ex.StackTrace);
}
//定义客户端
IPEndPoint sender=new IPEndPoint(IPAddress.Any,0);
clientEnd=(EndPoint)sender;
print("waiting for UDP dgram");
//开启一个线程连接,必须的,否则主线程卡死
connectThread=new Thread(new ThreadStart(SocketReceive));
connectThread.Start();
//开启一个线程连接,必须的,否则主线程卡死
connectThread2=new Thread(new ThreadStart(SocketReceive2));
connectThread2.Start();
}
void SocketSend(string sendStr)
{
//清空发送缓存
sendData=new byte[1024];
//数据类型转换
sendData=Encoding.ASCII.GetBytes(sendStr);
//发送给指定客户端
socket.SendTo(sendData,sendData.Length,SocketFlags.None,clientEnd);
}
//服务器接收
void SocketReceive()
{
//进入接收循环
while(true)
{
//对data清零
recvData=new byte[1024];
//获取客户端,获取客户端数据,用引用给客户端赋值
recvLen=socket.ReceiveFrom(recvData,ref clientEnd);
//输出接收到的数据
recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
char[] msgDelim = { '|' };
string[] asMessages = recvStr.Split(msgDelim);
if (asMessages.Length 7) {
queueClient1.Enqueue (recvStr);
if (int.Parse (asMessages [0]) == 2) {
if (int.Parse (asMessages [6]) == 6) { //wave
SetWaveCountsClient1 (2);
}
} else if (int.Parse (asMessages [0]) == 3) {
if (int.Parse (asMessages [6]) == 6) { //wave
SetWaveCountsClient2 (3);
}
}
}
}
}
//服务器接收
void SocketReceive2()
{
//进入接收循环
while(true)
{
//对data清零
recvData2=new byte[1024];
//获取客户端,获取客户端数据,用引用给客户端赋值
recvLen2=socket2.ReceiveFrom(recvData2,ref clientEnd);
//输出接收到的数据
recvStr2=Encoding.ASCII.GetString(recvData2,0,recvLen2);
char[] msgDelim = { '|' };
string[] asMessages = recvStr2.Split(msgDelim);
if (asMessages.Length 7)
{
queueClient2.Enqueue (recvStr2);
if (int.Parse(asMessages[0]) == 2)
{
if(int.Parse(asMessages[6]) == 6) //wave
{
SetWaveCountsClient1(2);
}
}
else if (int.Parse(asMessages[0]) == 3)
{
if (int.Parse(asMessages[6]) == 6) //wave
{
SetWaveCountsClient2(3);
}
}
}
}
}
public void SetWaveCountsClient1(int index)
{
if (index == 2)
{
WaveCounts[0]++;
}
}
public void SetWaveCountsClient2(int index)
{
if (index == 3)
WaveCounts[1]++;
}
public void SetTposeCounts(int index)
{
if (index == 2)
TPoseCounts[0]++;
else if (index == 3)
TPoseCounts[1]++;
}
public int GetWaveCounts(int index)
{
int ret = 0;
if (index == 2)
{
if (WaveCounts[0] 0)
ret = WaveCounts[0]--;
}
else if (index == 3)
{
if (WaveCounts[1] 0)
ret = WaveCounts[1]--;
}
return ret;
}
public int GetTposeCounts(int index)
{
int ret = 0;
if (index == 2)
{
if (TPoseCounts[0] 0)
ret = TPoseCounts[0]--;
}
else if (index == 3)
{
if (TPoseCounts[1] 0)
ret = TPoseCounts[1]--;
}
return ret;
}
//返回接收到的字符串
public string GetRecvStr()
{
string returnStr="";
//加锁防止字符串被改
if (queueClient1.Count 0)
{
lock (/*thisLock*/queueClient1) {
//returnStr=recvStr;
returnStr = queueClient1.Dequeue ();
}
}
return returnStr;
}
//返回接收到的字符串
public void setRecvStr()
{
//加锁防止字符串被改
lock(thisLock)
{
recvStr = null;
}
}
//返回接收到的字符串
public string GetRecvStr2()
{
string returnStr="";
if (queueClient2.Count 0)
{
lock (/*thisLock*/queueClient2) {
//returnStr=recvStr;
returnStr = queueClient2.Dequeue ();
}
}
return returnStr;
}
//返回接收到的字符串
public void setRecvStr2()
{
//加锁防止字符串被改
lock(thisLock)
{
recvStr2 = null;
}
}
//连接关闭
public void SocketQuit()
{
//关闭线程
if(connectThread!=null)
{
connectThread.Interrupt();
connectThread.Abort();
}
if(connectThread2!=null)
{
connectThread2.Interrupt();
connectThread2.Abort();
}
//最后关闭socket
if(socket!=null)
socket.Close();
//最后关闭socket
if(socket2!=null)
socket2.Close();
print("disconnect");
}
}
客户端代码如下:
using UnityEngine;
using System.Collections;
//引入库
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Xml;
//客户端
public class UdpHelpHandler : MonoBehaviour {
//以下默认都是私有的成员
Socket socket; //目标socket
EndPoint serverEnd; //服务端
IPEndPoint ipEnd; //服务端端口
string recvStr; //接收的字符串
string sendStr; //发送的字符串
byte[] recvData=new byte[1024]; //接收的数据,必须为字节
byte[] sendData=new byte[1024]; //发送的数据,必须为字节
int recvLen; //接收的数据长度
Thread connectThread; //连接线程
public bool isClient =true;
//初始化
public void InitSocket(string ipHostString,int port)
{
//定义连接的服务器ip和端口,可以是本机ip,局域网,互联网
ipEnd=new IPEndPoint(IPAddress.Parse(ipHostString),port);
//定义套接字类型,在主线程中定义
socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
//定义服务端
IPEndPoint sender=new IPEndPoint(IPAddress.Any,0);
serverEnd=(EndPoint)sender;
print("waiting for sending UDP dgram....");
//建立初始连接,这句非常重要,第一次连接初始化了serverEnd后面才能收到消息
//开启一个线程连接,必须的,否则主线程卡死
connectThread=new Thread(new ThreadStart(SocketReceive));
connectThread.Start();
}
public void SocketSend(string sendStr)
{
//清空发送缓存
sendData=new byte[1024];
//数据类型转换
sendData=Encoding.ASCII.GetBytes(sendStr);
//发送给指定服务端
socket.SendTo(sendData,sendData.Length,SocketFlags.None,ipEnd);
}
//服务器接收
void SocketReceive()
{
//进入接收循环
while(true)
{
// print("recv thread");
//对data清零
recvData=new byte[1024];
//获取客户端,获取服务端端数据,用引用给服务端赋值,实际上服务端已经定义好并不需要赋值
recvLen=socket.ReceiveFrom(recvData,ref serverEnd);
// print("message from: "+serverEnd.ToString()); //打印服务端信息
//输出接收到的数据
recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
// print(recvStr);
}
}
//连接关闭
public void SocketQuit()
{
//关闭线程
if(connectThread!=null)
{
connectThread.Interrupt();
connectThread.Abort();
}
//最后关闭socket
if(socket!=null)
socket.Close();
}
}
文章知识点与官方知识档案匹配
网络技能树首页概览
21577 人正在系统学习中
点击阅读全文
打开CSDN,阅读体验更佳
QT多线程,使用串口接收数据通过UDP端口进行数据转发_是小峰呀的博客-CS...
ui(newUi::Widget){ui-setupUi(this);socket=newQUdpSocket();localThread=newmyThread();timer=newQTimer();socket-bind(3080);//删除注释后,是由按钮控制数据发送,此时需要将带定时器的connet注释。
UDP数据通信,使用一个DatagramSocket实现向多个地址发送数据和接收各个...
往不同的服务器发送数据,只需要启动多个线程,调用上面的方法,替换地址和端口即可 //connect方法的意思是将socket与指定地址绑定,绑定成功后只能往该地址发送数据。并不是建立连接,因为udp是面向非连接的 mSocket.connect(address, hostPort...
c#向指定端口发送数据,监听指定端口
c#向指定端口发送数据,监听指定端口,使用端口监听获取数据信息,向指定端口发送需要的数据
最新发布 C# UDP发送和接收数据类
C# UDP发送和接收数据类
继续访问
UDP端口传递接收数据_wei395107171的博客
UDP端口传递接收数据 package com.udp.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket;...
...解决端口复用的问题)_酷侠一剑绝ggh的博客_udp端口复用
UDP组播通信(解决端口复用的问题) 最近在写一个组播通信的功能,结果发现接受同一台电脑上只能运行一个接收端,如果运行两个时,第二个运行的程序不能收到数据。查找原因是因为没有设置端口数据复用的功能(setsockpot),setsockpot的调用...
NIO之UDP监听多个端口获取请求信息
最近需要继承一个udp服务,需求是这样的,服务端接收消息,并且支持多个udp端口。 例如: 客户端:port 11112 port 11113 port 11114 服务端:要可以同时监听这三个端口,接收发送的报文。 Select监听端口,然后获取请求数据 附代码 @Override public void run(String... args) throws Exception {...
继续访问
UDP客户端实现在不同端口上发送和接收数据
普通udp通信,客户端在发送完数据后,只需要在相同socket上,recvfrom即可 服务端给的回应,可以是同一端口,也可以是不同端口,客户端在接收时,需要指点一个本地端口进行接收,此端口也可以用bind和创建的socket绑定。 但是bind必须是在通过这个socket发送数据前绑定,在发送数据后再bind会失败。 下面给出代码: #define SEND_PORT 8000
继续访问
发送方 获取 绑定 端口 linux c,多播报文的发送和接收
1实验目的掌握多播的原理及如何进行多播报文的发送和接受2注意事项需包括ws2tcpip.h文件发送者和所有接受者在同一网内不考虑TTL值,回环状态通过setsockopt( )函数设置选项来实现多播数据的发送和接收3试验流程3.1多播数据发送端流程l创建一个数据报套接口l设置多播地址(例:239.192.1.2)和端口号(例:12345)l调用setsockopt( )函数设置发送的数据报本地接口...
继续访问
网络编程之 Udp接收数据
udp接收数据,网络调试助手担任发送方,但发送时需要对方的也就是虚拟机的ip 和端口,ip可以通过config获取,那么如何让一个程序拥有一个固定端口呢? 创建套接字的时候是没有端口号的,好比买了手机没有手机号,别...
继续访问
C语言实现UDP服务器,客户端
服务器 #includestdio.h #include "unistd.h" #include "sys/socket.h" #include "netinet/in.h" #include "arpa/inet.h" #include "string.h" #include "stdlib.h" #define IP "127.0.0.1" #define PORT 8888 int main() { int fb=0,len=0; char buf[512]=
继续访问
c udp服务器端一对多持续接收消息,C - 使用select在多个端口上侦听的简单ipv6 udp服务器。从一个端口接收消息,而不是另一个...
#include #include #include #include #include int max(int socket_handle[]);int main(void){int max_clients_allowed = 2;int socket_handle[max_clients_allowed];int client_handle[max_clients_allowed];st...
继续访问
C# 简单的UDP服务器,实现异步接收UDP消息
C# 异步接收UDP消息 源代码 主要方法 async Task ListenForUdp(int port, ActionUdpReceiveResult receivedHandle) { using (var udpClient = new UdpClient(port)) { while (true) { try { receivedHandle(await
继续访问
UDP数据通信,使用一个DatagramSocket实现向多个地址发送数据和接收各个地址的数据返回
有时候需要一个客户端向多个地址发送数据并接收返回的需求 1、创建DatagramSocket DatagramSocket 有多个构造方法 DatagramSocket():创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、本机所有可用端口中随机选择的某个端口。 DatagramSocket(int prot):创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、指定端口。 DatagramSocket(int port, InetAddre.
继续访问
Python知识点——TCP和UDP的区别
相同点 UDP协议和TCP协议都是传输层协议。 TCP(Transmission Control Protocol,传输控制协议)提供的是面向连接,可靠的字节流服务。即客户和服务器交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据。并且提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。 UDP(User Data Protocol,用户数据报协议)是一个简单的面向数据报的运输层协议。它不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是不能保证它们能到达
继续访问
UDP多线程同时建立多个通信端口
1.需要注意的是:::bind(serSocket, (sockaddr*)serAddr, sizeof(serAddr)) == SOCKET_ERROR) ,bind()函数前必须添加::,否则,在使用thread头文件后,使用了using namespace std的情况下,会被默认成std::bind,导致编译失败 (1)server #includeWinS...
继续访问
C#winform UDP通信 发送和接收信息
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text;
继续访问
udp多线程 java_多线程以从多个UDP客户端接收数据
我想从不同的客户端接收数据(客户端数量是固定的,比如10),并且每个客户端在5个不同的预定义端口上发送数据,这些端口不会改变 . (例如,客户端1端口5000,5001,5002等) . 所有客户端都可以同时发送数据 . (以上都是固定的)在TCP中说,我可以为我们接受的每个连接创建多个线程,如下所示 . UDP is connectionless,So how can we create ...
继续访问
不同端口间的信息交换-使用udp协议
本文主要内容: 1.套接字(socket)简介; 2.udp简介; 3.udp发送数据及接收数据; 4.模拟qq聊天。 1.套接字(socket)简介 本地可以通过进程PID来唯一标识一个进程,但在网络中这是行不通的。ip地址可以唯一标识网络中的主机,传输层的“协议+端口号”可以唯一标识主机...
继续访问
c语言udp监听多个端口号,多个UDP监听同一个端口
测试结果:客户端的数据总是发给最后一个打开的服务器服务器代码:socket()-setsockopt()-bind()-recvfrom()/sendto()1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 91011 int main(int ar...
继续访问
udp接收多个端口的数据
请教用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例子
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();?
????????}?
????}?
}