VC实现最简单的UDP通信
C++udp通信
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
//发送数据
char szText[] = " TCP Server Demo! \r\n";
::sendto(s, szText, strlen(szText), 0, (sockaddr*)&addr, sizeof(addr));
turn 0;
}
//也可以在这里调用bind函数绑定一个本地地址
//否则系统将会自动安排
//填写远程地址信息
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(4567);
//注意,这里要填写服务器程序所在机器的IP地址
{
exit(0);
}
}
~CInitSock()
{
::WSACleanup();
}
};
//////////////////////////////////////////////////////////
// UDPClient文件
#include "../common/InitSock.h"
#include <stdio.h>
return 0;
}
//填充sockaddr_in结构
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(4567);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
UDP通信程序调试报告
UDP 通信实验调试报告一、调试内容:使用VC6.0作为开发平台,采用C语言编写udp程序,实现两台PC机通过以太网口传输数据。
两台PC机,一台运行开发程序,一台运行通信调试用端口精灵WizPort以太网口监视器作为程序调试辅助工具。
二、程序流程使用UDP通信程序运行步骤:①预先设置本机和目标机的IP地址和端口号②创建本机上的套接字socket③将套接字与本机的IP地址和端口号绑定④检测套接字设备文件的读写状态,接收和发送数据三、程序代码简析用Compaq Visual Fortran 6编译器可以调试程序#include <windows.h>#include <stdio.h>#include <conio.h>#include <string.h>#include <time.h>#include <errno.h>#include <stdlib.h>#include <sys/types.h>#include <winsock.h>#include <mmsystem.h>#include "nser.h"Udp应用程序除了涉及到一般的C语言库函数,还涉及到window功能调用,套接字函数调用,所以在VC开发平台默认的工程连接库中加入ws2_32.lib。
该库对应ws2_32.dll,提供了网络相关API的支持,若使用其中的API,则应该将ws2_32.lib加入工程。
在工程-->设置-->连接选项卡下的工程选项中输入ws2_32.lib(如上图)。
"nser.h"中定义了一些常用宏。
#define NTD_IPADDR "10.1.19.198"//ntd的ip地址#define NTD_PORT 3006 //nt的端口号#define LOCAL_IPADDR "10.1.19.199"//源端的ip地址#define LOCAL_PORT 3007 //源端的端口号以上定义了目标PC机和本地PC机的的IP地址和端口号。
c语言udp编程
c语言udp编程摘要:1.UDP 简介2.C 语言UDP 编程基础3.UDP 数据报结构4.UDP 发送和接收函数5.UDP 编程实例正文:【1.UDP 简介】UDP(User Datagram Protocol,用户数据报协议)是一种无连接的、不可靠的数据传输协议。
与TCP 协议相比,UDP 不建立连接,不保证数据包的可靠传输,但传输速度快,开销小。
因此,UDP 适用于那些对传输速度要求较高,能容忍部分丢包的数据传输场景,例如实时音视频传输。
【2.C 语言UDP 编程基础】在C 语言中,我们可以使用socket 库进行UDP 编程。
首先,需要包含相应的头文件:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>```然后,需要使用`socket`函数创建一个UDP 套接字:```cint sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);```其中,`AF_INET`表示使用IPv4 协议,`SOCK_DGRAM`表示UDP 套接字,`IPPROTO_UDP`表示UDP 协议。
【3.UDP 数据报结构】在C 语言中,UDP 数据报使用`struct sockaddr_in`结构表示。
这个结构包含了源IP 地址、目标IP 地址、源端口和目标端口等信息。
具体定义如下:```cstruct sockaddr_in {int8_t alen; // 地址长度,通常为4 字节int8_t s_addr; // 源IP 地址(网络字节序)int16_t s_port; // 源端口,网络字节序};```【4.UDP 发送和接收函数】发送UDP 数据包时,可以使用`sendto`函数:```cint sendto(int sock, const void *buf, int len, const struct sockaddr *addr);```接收UDP 数据包时,可以使用`recvfrom`函数:```cint recvfrom(int sock, void *buf, int len, struct sockaddr *addr, int *alen);```【5.UDP 编程实例】以下是一个简单的C 语言UDP 编程实例,实现了一个简单的客户端和服务器:服务器端代码:```cint main() {int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);struct sockaddr_in addr;addr.alen = sizeof(addr);addr.s_addr = htonl(INADDR_ANY);addr.s_port = htons(8888);bind(sock, (struct sockaddr *)&addr, sizeof(addr));while (1) {char buf[1024];int len = recvfrom(sock, buf, sizeof(buf), NULL, NULL);printf("收到消息:%s", buf);}return 0;}```客户端代码:```cint main() {int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);struct sockaddr_in addr;addr.alen = sizeof(addr);addr.s_addr = inet_addr("127.0.0.1");addr.s_port = htons(8888);while (1) {char buf[1024] = "Hello, UDP!";sendto(sock, buf, sizeof(buf), (struct sockaddr *)&addr, sizeof(addr));}return 0;}```分别编译并运行服务器端和客户端代码,可以看到服务器端能接收到客户端发送的消息。
UDP通讯 实验报告
物理与电子工程学院《嵌入式系统设计》设计性实验报告题目UDP通讯实验系别物电学院电子信息工程年级2009 专业电子信息工程班级Y091 学号Y10109139学生姓名吴晓婷指导教师浦炜实验时间2012/10/9目录课题要求 (2)1.本课题的目的 (2)2.运行环境 (2)正文 (2)一.课题分析 (2)二.系统设计 (3)三.技术实现问题 (6)四.总结与体会 (7)设计性实验报告成绩:指导教师签名: (7)课题要求1.本课题的目的学习UDP 通讯原理并掌握Socket编程方法。
编程实现嵌入式开发平台和计算机之间的UDP 通讯。
通过触摸屏进行画图,使其在液晶屏上显示,同时通过网络传输数据,使其在计算机屏幕上显示;由计算机控制清除液晶屏上的图形。
在此基础上,通过小键盘控制在触摸屏上绘制的图形,如按键后控制绘矩形或圆形等,通过双击清屏等功能。
2.运行环境硬件:ARM 嵌入式开发板、ARM7TDMI 的JTAG 仿真器、PC 机Pentium100 以上。
软件:PC 机操作系统win98、Win2000 或WinXP、ARM SDT 2.51 或ADS1.2 集成开发环境、仿真器驱动程序、超级终端通讯程序正文一.课题分析1.UDP 协议简介UDP 协议即用户数据报协议(User Datagram Protocol),它与我们所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。
根据OSI(开放系统互连)参考模型,UDP 和TCP 都属于传输层协议。
UDP 协议的主要作用是将网络数据流压缩成数据报的形式。
一个典型的数据报就是一个二进制数据的传输单位。
每一个数据报的前8 个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。
UDP 报头由4 个域组成,其中每个域各占用2 个字节。
UDP 协议使用端口号为不同的应用保留其各自的数据传输通道。
UDP协议正是采用这一机制实现对同一时刻内多项应用同时发送和接收数据的支持。
Windows下C语言的Socket编程例子(TCP和UDP)
Windows下C语言的Socket编程例子(TCP和UDP)sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基于TCP的socket编程是采用的流式套接字。
在这个程序中,将两个工程添加到一个工作区。
要链接一个ws2_32.lib的库文件。
服务器端编程的步骤:1:加载套接字库,创建套接字(WSAStartup()/socket());2:绑定套接字到一个IP地址和一个端口上(bind());3:将套接字设置为监听模式等待连接请求(listen());4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());5:用返回的套接字和客户端进行通信(send()/recv());6:返回,等待另一连接请求;7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
客户端编程的步骤:1:加载套接字库,创建套接字(WSAStartup()/socket());2:向服务器发出连接请求(connect());3:和服务器端进行通信(send()/recv());4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
函数介绍:1.#include<sys/socket.h>int socket (int family, int type, int protocol);返回值,成功为非负整数,成为套接口描数字;出错为-1、family参数:AF_INET --ipv4;AF_INET6--ipv6;AF_LOCAL--unix域协议;AF_ROUTE--路由socket;AF_KEY--密钥socket;type参数:SOCK_STREAM--字节流套接口SOCK_DGRAM--数据报套接口SOCK_RAM--原始套接口protocal参数一般置为0,当type为SOCK_RAM时不同2.#include<sys/socket.h>int connect (int sockfd, const struct sockaddr* servaddr, socklen_t addlen);返回值,0-成功;-1-出错;servaddr参数可以为sockaddr_in和sockaddr_in6类型,但是都必须强制转化为sockaddr指针类型;connect函数的出错处理:(1)ETIMEOUT-connection timed out 目的主机不存在,没有返回任何相应,例如主机关闭(2)ECONNREFUSED-connection refused(硬错)到达目的主机后,由于各种原因建立不了连接,主机返回RST(复位)响应,例如主机监听进程未启用,tcp取消连接等(3)EHOSTTUNREACH-no route to host(软错)路由上引发了一个目的地不可达的ICMP错误其中(1)(3),客户端会进行定时多次重试,一定次数后才返回错误。
C# TcpUdp使用详解
TcpClient BeginConnect
开始一个对远程主机连接的异步请求
EndConnect
异步接受传入的连接尝试
Socket BeginReceive
开始从连接的 Socket 中异步接收数据
EndReceive
结束挂起的异步读取
BeginSend
将数据异步发送到连接的 Socket
EndSend
3.TcpClient tcpClient = new TcpClient(IPEndPoint iep);参数 iep 指定本机(客户 端)IP 地址很端口号。当客户端存在一个以上的 IP 地址。 IPAddress[] address = Dns.GetHostAddresses(Dns.GetHostName()); IPEndPort iep = new IPEndPoint(address[0],51888); TcpClient tcpClient = new TcpClient(); tcpClient.Connect("",51888); 4.TcpClient(string hostname,int port);hostname:连接的远程主机的 DNS 名,port 表示要连接到的远程主机的端口号。 TcpClient tcpClient = new TcpClient("",51888); TcpClient 类的常用属性:
if(needExit) break;
Thread.Sleep(50); } 3.使用 EndInvoke 结束异步调用: private struct SendMessageStates{
public SendMessageDelegate d; public IAsyncResult result; } private void AsyncSendMessage(string message) { SendMessageDelegate d = new SendMessageDelegate(SendMessage); IAsyncResult result = d.BeginInvoke(message,null,null); while(result.IsCompleted == false) {
C语言socket编程----实现UDP通信
C语⾔socket编程----实现UDP通信TCP/IP协议叫做传输控制/⽹际协议,⼜叫做⽹络通信协议。
实际上,它包括上百个功能的协议。
套接字(socket):在⽹络中⽤来描述计算机中不同程序与其他计算程序的通信⽅式。
套接字分为三类;流式socket(SOCK_STREAM):提供可靠,⾯向连接的通信流;它使⽤TCP协议,从⽽保证了数据传输的正确性和顺序性。
数据报socket(SOCK_DGRAM):数据报套接字定义了⼀种⽆连接的服务,数据通过相互独⽴的报⽂进⾏传输,⽆序的,并且不保证可靠,⽆差错的。
它使⽤的数据报协议是UDP。
原始socket:原始套接字允许对底层协议如TP或ICMP进⾏直接访问,它功能强⼤但使⽤复杂,主要⽤于⼀些协议的开发。
下⾯是UDP通信的demo://socket udp 服务端1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/socket.h>5 #include<arpa/inet.h>67int main()8 {9//创建socket对象10int sockfd=socket(AF_INET,SOCK_DGRAM,0);1112//创建⽹络通信对象13struct sockaddr_in addr;14 addr.sin_family =AF_INET;15 addr.sin_port =htons(1324);16 addr.sin_addr.s_addr=inet_addr("127.0.0.1");1718//绑定socket对象与通信链接19int ret =bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));20if(0>ret)21 {22 printf("bind\n");23return -1;2425 }26struct sockaddr_in cli;27 socklen_t len=sizeof(cli);2829while(1)30 {31char buf =0;32 recvfrom(sockfd,&buf,sizeof(buf),0,(struct sockaddr*)&cli,&len);33 printf("recv num =%hhd\n",buf);3435 buf =66;36 sendto(sockfd,&buf,sizeof(buf),0,(struct sockaddr*)&cli,len);3738 }39 close(sockfd);4041 }//socket udp 客户端1 #include<stdio.h>2 #include<sys/types.h>3 #include<sys/socket.h>4 #include<unistd.h>5 #include<arpa/inet.h>67int main()8 {9//创建socket对象10int sockfd=socket(AF_INET,SOCK_DGRAM,0);1112//创建⽹络通信对象13struct sockaddr_in addr;14 addr.sin_family =AF_INET;15 addr.sin_port =htons(1324);16 addr.sin_addr.s_addr = inet_addr("192.168.0.143");1718while(1)19 {20 printf("请输⼊⼀个数字:");21char buf=0;22 scanf("%hhd",&buf);23 sendto(sockfd,&buf,24sizeof(buf),0,(struct sockaddr*)&addr,sizeof(addr));2526 socklen_t len=sizeof(addr);27 recvfrom(sockfd,&buf,sizeof(buf),0,(struct sockaddr*)&addr,&len); 2829if(66 ==buf)30 {31 printf(" server 成功接受\n");32 }33else34 {35 printf("server 数据丢失\n");36 }3738 }39 close(sockfd);4041 }。
VisualC设计UDP协议通信例如
Visual C++设计UDP协议通信例如一、绪言UDP是一种面向非连接,不靠得住的通信协议,相关于TCP来讲,尽管靠得住性不及,但传输效率较高。
因此在网络上仍有专门大的用途。
这几日需要了解下udp通信的进程,上网发觉这方面的资料还挺少。
于是认真的翻找了下msdn,大体上弄清楚了udp通信的进程。
做了一个测试的例子。
希望对大伙儿有帮忙。
二、UDP的通信进程server端: open a socket(socket)--->name the socket(bind)--->send and receive data(sendto recvfrom)--->close socket(closesocket)client端: open a socket(socket)---------------------------->send and receive data(sendto recvfrom)--->close socket(closesocket)server端无需listen,client端无需connect,因此udp中server和client的区别相对较模糊。
只要挪用sendto和recvfrom就能够够给指定的地址收发数据,但并非保证收发的数据的完整性和靠得住性。
三、例如udpserver要紧代码:void main(){SOCKET socket1;InitWinsock();struct sockaddr_in local;struct sockaddr_in from;int fromlen =sizeof(from);=AF_INET;=htons(1000); ///监听端口=INADDR_ANY; ///本机socket1=socket(AF_INET,SOCK_DGRAM,0);bind(socket1,(struct sockaddr*)&local,sizeof local);while (1){char buffer[1024]="\0";printf("waiting for message from others-------------\n");if (recvfrom(socket1,buffer,sizeof buffer,0,(structsockaddr*)&from,&fromlen)!=SOCKET_ERROR){printf("Received datagram from %s--%s\n",inet_ntoa(),buffer); ////给cilent发信息sendto(socket1,buffer,sizeof buffer,0,(structsockaddr*)&from,fromlen);}Sleep(500);}closesocket(socket1);}udpcilent要紧代码:void main(){SOCKET socket1;InitWinsock();struct sockaddr_in server;int len =sizeof(server);=AF_INET;=htons(1000); ///server的监听端口=inet_addr("168.168.0.10"); ///server的地址socket1=socket(AF_INET,SOCK_DGRAM,0);while (1){char buffer[1024]="\0";printf("input message\n");scanf("%s",buffer);if (strcmp(buffer,"bye")==0)break;if (sendto(socket1,buffer,sizeof buffer,0,(structsockaddr*)&server,len)!=SOCKET_ERROR){if (recvfrom(socket1,buffer,sizeof buffer,0,(struct sockaddr*)&server,&len) != SOCKET_ERROR)printf("rece from server:%s\n",buffer);}}closesocket(socket1);}四、终止语UDP通信比TCP简单了很多,在数据靠得住性不是很高的情形下,有利用的价值。
c语言udp组播编程
c语言udp组播编程C语言UDP组播编程UDP是一种无连接的协议,使用它进行消息传递时,不需要建立连接。
而组播(Multicast)传输是一种数据发送方式,数据只需要发送一次,就可以同时被多个接收者接收,这种方式省去了重复发送数据的开销,也减轻了网络负担。
C语言中,我们可以使用socket API来进行UDP组播编程。
以下是一个基本的UDP组播通信的实现流程:1. 创建一个UDP套接字可以使用socket函数来创建一个UDP套接字。
代码如下:```cint sockfd;struct sockaddr_in addr;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){perror("socket error");exit(EXIT_FAILURE);}```2. 绑定端口和IP地址在使用UDP通信时,需要绑定端口和IP地址。
代码如下:```cmemset(&addr, 0 , sizeof addr);addr.sin_family = AF_INET;addr.sin_addr.s_addr = htonl(INADDR_ANY);addr.sin_port = htons(PORT);if(bind(sockfd, (struct sockaddr *)&addr, sizeof addr) == -1){ perror("bind error");exit(EXIT_FAILURE);}```其中,PORT是定义的端口号。
3. 加入组播组需要使用setsockopt函数加入组播组。
代码如下:```cstruct ip_mreq mreq;mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_ADDR);mreq.imr_interface.s_addr = htonl(INADDR_ANY);if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) == -1){perror("setsockopt");exit(EXIT_FAILURE);}```其中,MULTICAST_ADDR为组播组地址。
C语言干UDP聊天程序实现总结1和2
与之对应的 UDP 编程步骤要简单许多,分别如下: UDP 编程的服务器端一般步骤是: 1、创建一个 socket,用函数 socket(); 2、绑定 IP 地址、端口等信息到 socket 上,用函数 bind(); 3、循环接收数据,用函数 recvfrom(); 4、关闭网络连接;
int retval;
//我们这里采用无限循环来使它接收数据直到对方关闭。 while(TRUE) { //因为我们是用 UDP 的方式。所以我们这里用 recvform 来接收数据。
若是 TCP 则采用 recv。 //recvform 的参数。第一是套接字,第二个是你要接收的字符缓冲区。第
三个是缓冲区大小。第四个是标记我们设为 0 就好。 //第五个参数是接收对方地址。第六个是地址长度。
SOCKET server=((LPINFO*)lp)->server; HWND hwnd = ((LPINFO*)lp)->Hwnd; //同样由于我们这里是接收数据的,我们就的再申明一个接收端的地址变量。 以便于接收端用户能用到。 SOCKADDR_IN addrfrom;//定义接收端地址信息。 int len = sizeof(SOCKADDR); TCHAR recvBuf[256]; TCHAR tempBuf[512]; TCHAR Buff[LARGE]; TCHAR cUseName[50]; TCHAR cResult[50]; SYSTEMTIME time;//时间结构体变量。
C语言实现UDP网络传输
C语言实现UDP网络传输UDP(User Datagram Protocol,用户数据报协议)是一种面向无连接的传输协议,它在网络编程中具有重要的作用。
本文将介绍C语言如何实现UDP网络传输的基本原理和步骤。
一、UDP网络传输简介UDP是一种简单的传输层协议,相对于TCP(Transmission Control Protocol,传输控制协议)来说,UDP更加轻量级。
它不提供可靠性和流量控制,但是具有实时性较高的特点,适用于需要快速传输数据的场景,如音频、视频等实时应用。
UDP协议的数据包格式主要包括源端口号、目标端口号、长度、校验和以及数据。
由于UDP是无连接的,所以每个数据包都是独立发送的,不需要建立和维护连接,这使得UDP的实现相对简单。
二、C语言实现UDP网络传输步骤要使用C语言实现UDP网络传输,我们需要按照以下步骤进行操作:1. 创建套接字(Socket)在C语言中,使用socket()函数创建一个套接字,该套接字用于后续的数据传输。
在创建套接字时,需要指定协议簇(AF_INET代表IPv4)和套接字类型(SOCK_DGRAM代表使用UDP协议)。
2. 绑定本地地址和端口号使用bind()函数将套接字与本地地址和端口号绑定,以便接收数据和发送数据。
通常将本地地址设置为INADDR_ANY,端口号可以自定义。
3. 接收数据使用recvfrom()函数接收远程主机发送的数据,该函数会将接收到的数据存储到指定的缓冲区中,并返回接收到的字节数。
可以通过指定发送方的地址和端口号来实现数据的精确接收。
4. 发送数据使用sendto()函数将数据发送给目标主机,该函数需要指定目标主机的地址和端口号,并将待发送的数据和数据长度作为参数传入。
5. 关闭套接字使用close()函数关闭套接字,释放资源。
三、C语言实现UDP网络传输示例代码```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <arpa/inet.h>#define MAX_BUFFER_SIZE 1024#define SERVER_PORT 8888#define SERVER_IP "127.0.0.1"int main() {int sockfd;char buffer[MAX_BUFFER_SIZE];struct sockaddr_in server_addr, client_addr;socklen_t client_len = sizeof(client_addr);// 创建套接字sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("Error in creating socket");exit(1);}memset(&server_addr, 0, sizeof(server_addr));memset(&client_addr, 0, sizeof(client_addr));// 设置服务器地址和端口号server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);// 绑定本地地址和端口号if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {perror("Error in binding");exit(1);}printf("Server is listening for incoming connections...\n");while (1) {// 接收数据memset(buffer, 0, sizeof(buffer));ssize_t recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, &client_len);if (recv_len < 0) {perror("Error in receiving data");exit(1);}printf("Received data from client: %s\n", buffer);// 发送数据const char* msg = "Hello, client!";ssize_t send_len = sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*)&client_addr, client_len);if (send_len != strlen(msg)) {perror("Error in sending data");exit(1);}printf("Sent response to client: %s\n", msg);}// 关闭套接字close(sockfd);return 0;}```以上是一个简单的UDP服务器示例代码,它通过创建套接字、绑定地址和端口、接收数据并发送响应的方式来实现UDP网络传输。
基于VC的UDP的实现
数 据 方 发 送 数 据 后 . 须 等 到 接 受 数 据 方 发 回 了接 受 到 了 必
数 据 的 信 息 后 .才 能 做 下 面 的 事 情 ; 作 为 接 收 数 据 方 . 而 在 决 定 接 收 后 . 须 接 收 到 数 据 后 才 能 做 下 面 的 事 情 , 需 要 必 它 不 断 地 轮 询 接 收 缓 冲 区有 没 有 数 据 . 称 为阻 塞 方 式 。异 步 又 则 是 在 发 送 和 接 收 数 据 时 还 可 以做 其 它 的 事 情 , 称 为 非 阻 又
维普资讯
同 步 就 是 发 送 和 接 受 数 据 的 双 方 保 持 步 调 一 致 .发 送
e r W SAS a t p wVe so r— t ru ( rinRe u se , ws Daa ; q e td & a t) i e r『 ){e u n; f(r _0 r t r }
。
a s e
C h
,
d
n
—
o n
h
u a
。
V C
in g
u a n
g L i y
n
L i
n
ju
n
.
e n
J i
e
p
a r
tm
e n t
o
f E le C h
e n
c
t
r o n
ic U
n
a n
d I
e r s
fo
r m
a
t io
e c
n
E
n o
g in
,
e e r
in g h
T h
E
n
g in
孙鑫VC视频教程笔记之第十四课“基于TCP和UDP的Socket编程”
在OSI的各层所使用的协议:1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP32.传输层:TCP,UDPTCP:面向连接的可靠的传输协议,通信前建立三次握手,握手成功后才能通信,对数据准确性要求较高的场合使用,如从网上载的安装文件,不能缺少任何信息UDP:是无连接的,不可靠的传输协议,不需要建立连接,也没有重传和确认的机制,在实时性要求较高,但对数据准确度要求不是很高的场合使用,如视频会议,在线观看电影,当中丢失个别数据包并不影响整体的效果。
3.网络层:IP因为OSI七层结构较为复杂,所以使用较多的是TCP/IP模型,现在TCP/IP已经成为Internet 上通用的工业标准TCP/IP模型包括4个层次:应用层,传输层,网络层,网络接口端口:1. 为了标识通信实体中进行通信的进程(应用程序),TCP/IP协议提出了协议端口的概念2. 端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。
应用程序通过系统调用和某端口建立连接(binding)后,传输层传给该端口的数据都被相应的进程所接收,相应进程发给传输层的数据都通过该端口输出3. 端口用一个整数型标识符来表示,即端口号。
端口号跟协议相关,TCP/IP传输层的两个协议TCP和UDP是完全独立的的两个软件模块,因此各自的端口号也相互独立4. 端口使用一个16位的数字来表示,它的范围是0~65535,1024以下的端口号保留给预定义的服务,例如,http使用80端口套接字(Socket)1. Socket的出现,使得程序员可以很方便的访问TCP/IP,从而开发各种网络应用的程序2. 套接字存在于通信区域中,通信区域也叫地址族,他是一个抽象的概念,主要用于通过套接字通信的进程的共有特性综合在一起。
套接字通常只与同一个区域的套接字交换数据。
套接字的类型1. 流式套接字(SOCK_STREAM)提供面向连接的,可靠的数据传输服务,数据无差错,无重复的发送,且按发送的顺序接收,基于TCP协议2. 数据保式套接字(SOCK_DGRAM)提供无连接的服务,数据包以独立包形式发送,不提供无错误的保证,数据可能丢失或重复,且接收顺序混乱,基于UDP协议基于TCP(面向连接)的Socket编程服务器端顺序:1. 加载套接字库2. 创建套接字(socket)3. 将套接字绑定到一个本地地址和端口上(bind)4. 将套接字设为监听模式,准备接收客户请求(listen)5. 等待客户请求的到来;当请求带来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)6. 用返回的套接字和客户端进行通信(send/recv)7. 返回,等待另一个客户请求8. 关闭套接字(closesocket)客户端程序:1. 加载套接字库2. 创建套接字(socket)3. 向服务器发送连接请求(connect)4. 和服务器端进行通信(send/receive)5. 关闭套接字(closesocket)基于UDP(面向无连接)的socket编程服务器端(接收端)程序:1. 加载套接字库2. 创建套接字(socket)3. 将套接字绑定到一个本地地址和端口上(bind)4. 等待接收数据(recvfrom)5. 关闭套接字(closesocket)客户端(发送端)程序1. 加载套接字库2. 创建套接字(socket)3. 向服务器发送数据(sendto)4. 关闭套接字(closesocket)创建基于TCP协议的CS程序的Server端所涉及的相关函数说明(按使用的先后顺序排列):1. int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData):作用是加载套接字库和进行套接字库的版本协商a. 参数wVersionRequested:用于指定准备加载的Winsock库的版本,高位字节指定所需要的Winsock库的副版本,低位字节则是主版本,可用MAKEWORD(X,Y)(其中,x为高位字节,y为低位字节)方便获得wVersionRequested的正确值。
Windows下C语言的Socket编程例子(TCP和UDP)+++
一。
<TCP>server端:1 #include "stdafx.h"2 #include <stdio.h>3 #include <winsock2.h>45#pragma comment(lib,"ws2_32.lib")67int main(int argc, char* argv[])8 {9//初始化WSA10 WORD sockVersion = MAKEWORD(2,2);11 WSADATA wsaData;12if(WSAStartup(sockVersion, &wsaData)!=0)13 {14return0;15 }1617//创建套接字18 SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);19if(slisten == INVALID_SOCKET)20 {21 printf("socket error !");22return0;23 }2425//绑定IP和端口26 sockaddr_in sin;27 sin.sin_family = AF_INET;28 sin.sin_port = htons(8888);29 sin.sin_addr.S_un.S_addr = INADDR_ANY;30if(bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)31 {32 printf("bind error !");33 }3435//开始监听36if(listen(slisten, 5) == SOCKET_ERROR)37 {38 printf("listen error !");39return0;40 }4142//循环接收数据43 SOCKET sClient;44 sockaddr_in remoteAddr;45int nAddrlen = sizeof(remoteAddr);46char revData[255];47while (true)48 {49 printf("等待连接...\n");50 sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);51if(sClient == INVALID_SOCKET)52 {53 printf("accept error !");54continue;55 }56 printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));5758//接收数据59int ret = recv(sClient, revData, 255, 0);60if(ret > 0)61 {62 revData[ret] = 0x00;63 printf(revData);64 }6566//发送数据67char * sendData = "你好,TCP客户端!\n";68 send(sClient, sendData, strlen(sendData), 0);69 closesocket(sClient);70 }7172 closesocket(slisten);73 WSACleanup();74return0;75 }client端:1 #include "stdafx.h"2 #include <WINSOCK2.H>3 #include <STDIO.H>45#pragma comment(lib,"ws2_32.lib")678int main(int argc, char* argv[])9 {10 WORD sockVersion = MAKEWORD(2,2);11 WSADATA data;12if(WSAStartup(sockVersion, &data) != 0)13 {14return0;15 }1617 SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);18if(sclient == INVALID_SOCKET)19 {20 printf("invalid socket !");21return0;22 }2324 sockaddr_in serAddr;25 serAddr.sin_family = AF_INET;26 serAddr.sin_port = htons(8888);27 serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");28if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)29 {30 printf("connect error !");31 closesocket(sclient);32return0;33 }34char * sendData = "你好,TCP服务端,我是客户端!\n";35 send(sclient, sendData, strlen(sendData), 0);3637char recData[255];38int ret = recv(sclient, recData, 255, 0);39if(ret > 0)40 {41 recData[ret] = 0x00;42 printf(recData);43 }44 closesocket(sclient);45 WSACleanup();46return0;47 }二. <UDP>SERVER 端1 #include "stdafx.h"2 #include <stdio.h>3 #include <winsock2.h>45#pragma comment(lib, "ws2_32.lib")67int main(int argc, char* argv[])8 {9 WSADATA wsaData;10 WORD sockVersion = MAKEWORD(2,2);11if(WSAStartup(sockVersion, &wsaData) != 0)12 {13return0;14 }1516 SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);17if(serSocket == INVALID_SOCKET)18 {19 printf("socket error !");20return0;21 }2223 sockaddr_in serAddr;24 serAddr.sin_family = AF_INET;25 serAddr.sin_port = htons(8888);26 serAddr.sin_addr.S_un.S_addr = INADDR_ANY;27if(bind(serSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)28 {29 printf("bind error !");30 closesocket(serSocket);31return0;32 }3334 sockaddr_in remoteAddr;35int nAddrLen = sizeof(remoteAddr);36while (true)37 {38char recvData[255];39int ret = recvfrom(serSocket, recvData, 255, 0, (sockaddr *)&remoteAddr, &nAddrLen);40if (ret > 0)41 {42 recvData[ret] = 0x00;43 printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));44 printf(recvData);45 }4647char * sendData = "一个来自服务端的UDP数据包\n";48 sendto(serSocket, sendData, strlen(sendData), 0, (sockaddr *)&remoteAddr,nAddrLen);4950 }51 closesocket(serSocket);52 WSACleanup();53return0;54 }CLIENT 端1 #include "stdafx.h"2 #include <stdio.h>3 #include <winsock2.h>45#pragma comment(lib, "ws2_32.lib")67int main(int argc, char* argv[])8 {9 WORD socketVersion = MAKEWORD(2,2);10 WSADATA wsaData;11if(WSAStartup(socketVersion, &wsaData) != 0)12 {13return0;14 }15 SOCKET sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);1617 sockaddr_in sin;18 sin.sin_family = AF_INET;19 sin.sin_port = htons(8888);20 sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");21int len = sizeof(sin);2223char * sendData = "来自客户端的数据包.\n";24 sendto(sclient, sendData, strlen(sendData), 0, (sockaddr *)&sin, len); 2526char recvData[255];27int ret = recvfrom(sclient, recvData, 255, 0, (sockaddr *)&sin, &len); 28if(ret > 0)29 {30 recvData[ret] = 0x00;31 printf(recvData);32 }3334 closesocket(sclient);35 WSACleanup();36return0;37 }。
c语言udp通讯例程
c语言udp通讯例程以下是一个简单的 C 语言 UDP 通讯例程,包括一个发送端和一个接收端:**发送端代码(sender.c):**```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>void sendMessage(int sock, const char *message) {size_t messageLength = strlen(message);// 发送数据send(sock, message, messageLength, 0);}int main() {int sock;struct sockaddr_in serverAddress;char message[1024];// 创建 UDP 套接字if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {perror("Failed to create socket");exit(EXIT_FAILURE);}// 设置服务器地址serverAddress.sin_family = AF_INET;serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); // 请将这里的地址替换为接收端的实际 IP 地址serverAddress.sin_port = htons(54321); // 请将这里的端口替换为接收端的实际端口printf("Enter a message: ");scanf("%s", message);// 发送消息sendMessage(sock, message);// 关闭套接字close(sock);return 0;}```**接收端代码(receiver.c):**```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>void receiveMessage(int sock) {char message[1024];size_t messageLength;// 接收数据messageLength = recv(sock, message, sizeof(message) - 1, 0);message[messageLength] = '\0';printf("Received message: %s\n", message);}int main() {int sock;struct sockaddr_in serverAddress;socklen_t serverAddressLength = sizeof(serverAddress);// 创建 UDP 套接字if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {perror("Failed to create socket");exit(EXIT_FAILURE);}// 绑定套接字到本地地址serverAddress.sin_family = AF_INET;serverAddress.sin_addr.s_addr = INADDR_ANY;serverAddress.sin_port = htons(54321); // 请确保这里的端口与发送端使用的端口相同if (bind(sock, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) == -1) {perror("Failed to bind socket");exit(EXIT_FAILURE);}// 接收消息receiveMessage(sock);// 关闭套接字close(sock);return 0;}```这个例子中,发送端发送一个 UDP 数据包到接收端,接收端接收到数据包并打印出消息内容。
VC中网络编程的常用函数及UDP,TCP协议编程步骤
VC中网络编程的常用函数及UDP,TCP协议编程步骤编写:<单击输入编写人>1.SOCKET类型SOCKET是socket套接字类型,在WINSOCK2.H中有如下定义:typedef unsigned int u_int;typedef u_int SOCKET;可知套接字实际上就是一个无符号整型,它将被Socket环境管理和使用。
套接字将被创建、设置、用来发送和接收数据,最后会被关闭。
2.WORD类型、MAKEWORD、LOBYTE和HIBYTE宏WORD类型是一个16位的无符号整型,在WTYPES.H中被定义为:typedef unsigned short WORD;其目的是提供两个字节的存储,在Socket中这两个字节可以表示主版本号和副版本号。
使用MAKEWORD宏可以给一个WORD类型赋值。
例如要表示主版本号2,副版本号0,可以使用以下代码:WORD wVersionRequested; wVersionRequested = MAKEWORD( 2, 0 );注意低位内存存储主版本号2,高位内存存储副版本号0,其值为0x0002。
使用宏LOBYTE可以读取WORD的低位字节,HIBYTE可以读取高位字节。
3. WSADATA类型和LPWSADATA类型WSADATA类型是一个结构,描述了Socket库的一些相关信息,其结构定义如下:typedef struct WSAData {WORD wVersion;WORD wHighVersion;char szDescription[WSADESCRIPTION_LEN+1];char szSystemStatus[WSASYS_STATUS_LEN+1];unsigned short iMaxSockets;unsigned short iMaxUdpDg;char FAR * lpVendorInfo;} WSADATA;typedef WSADATA FAR *LPWSADATA;值得注意的就是wVersion字段,存储了Socket的版本类型。
基于C#的UDP通信(使用UdpClient实现,包含发送端和接收端)
基于C#的UDP通信(使⽤UdpClient实现,包含发送端和接收端)UDP不属于⾯向连接的通信,在选择使⽤协议的时候,选择UDP必须要谨慎。
在⽹络质量令⼈⼗分不满意的环境下,UDP协议数据包丢失会⽐较严重。
但是由于UDP的特性:它不属于连接型协议,因⽽具有资源消耗⼩,处理速度快的优点,所以通常⾳频、视频和普通数据在传送时使⽤UDP较多,因为它们即使偶尔丢失⼀两个数据包,也不会对接收结果产⽣太⼤影响。
⽐如我们聊天⽤的ICQ和QQ就是使⽤的UDP协议。
我们通过UDP进⾏信息收发的时候,没有严格客户端和服务端的区别,它不同于UDP,UDP 必须建⽴可靠连接之后才可以通信,⽽UDP随时都可以给指定的ip和端⼝所对应进程发送消息。
UDP发送消息时需要绑定⾃⼰IP 和端⼝号,接收消息的时候没有特殊限制,只要有⼈给⾃⼰发送,⾃⼰在线,就可以接收。
(⽹上例⼦很多,但是总有⼀点地⽅看不懂。
下⾯附上我的⼩例⼦,仅供参考。
)发送端:1using System;2using System.Text;3using System.Windows.Forms;4using .Sockets;5using ;67namespace client8 {9public partial class Form1 : Form10 {11public Form1()12 {13 InitializeComponent();14 }1516//初始化⼀个UdpClient的新实例17 UdpClient sendUdpClient = new UdpClient();1819//单击事件20private void btn_send_Click(object sender, EventArgs e)21 {22string message = txt_sendmsg.Text;2324if(string.IsNullOrEmpty(message))25 {26 MessageBox.Show("发送内容不能为空!");27 txt_sendmsg.Focus();28return;29 }3031//⽤指定IP地址和端⼝号初始化IPEndPoint类的新实例32 IPEndPoint local = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);3334//将数据报发送⾄指定主机35 sendUdpClient.Send(Encoding.UTF8.GetBytes(message), message.Length, local);3637 }38 }39 }View Code接收端:1using System;2using System.Text;3using System.Windows.Forms;4using ;5using .Sockets;6using System.Threading;78namespace server9 {10public partial class Form1 : Form11 {12public Form1()13 {14 InitializeComponent();15 }1617private void Form1_Load(object sender, EventArgs e)18 {19//初始化新线程⽤来接收消息20 Thread myThread = new Thread(ReceiveMsg);2122//设为后台线程23 myThread.IsBackground = true;2425//开启线程26 myThread.Start();27 }2829private UdpClient receiveUdpClient;3031private const int port = 8888;3233 IPAddress ip = IPAddress.Parse("127.0.0.1");3435//接收消息36private void ReceiveMsg()37 {38//⽤指定IP地址和端⼝号初始化IPEndPoint类的新实例39 IPEndPoint local = new IPEndPoint(ip, port);4041//初始化⼀个UdpClient的新实例并绑定到本地42 receiveUdpClient = new UdpClient(local);4344while(true)45 {46try47 {48//返回由主机发来的数据报49byte[] receiveBytes = receiveUdpClient.Receive(ref local);5051string receivemsg = Encoding.UTF8.GetString(receiveBytes, 0, receiveBytes.Length);52 ShowMessage(lst_receivemsg, receivemsg);53 }54catch55 {56break;57 }58 }59 }6061// 通过委托回调机制显⽰消息内容62delegate void ShowMessageDelegate(ListBox listbox, string text);6364private void ShowMessage(ListBox listbox, string text)65 {66//如果控件的 Handle 是在与调⽤线程不同的线程上创建的(此时,您必须通过 Invoke ⽅法对控件进⾏调⽤),则为 true;否则为 false。
VC实现最简单的UDP通信
VC实现最简单的UDP通信UDP(User Datagram Protocol)是一种无连接的传输层协议,它提供了一种不可靠、无序的数据包传输方式。
与TCP不同,UDP没有错误纠正机制和拥塞控制机制,因此适合发送不需要可靠传输的数据,如音频、视频等。
下面将介绍如何用VC实现最简单的UDP通信。
首先,在VC中创建一个新的工程。
选择“新建项目”,然后选择“Win32项目”。
1.创建UDP套接字在工程中的源文件中,包含以下头文件:```c++#include <WinSock2.h>#include <iostream>```初始化Winsock库:```c++WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)std::cout << "Failed to initialize winsock" << std::endl;return 1;```创建UDP套接字:```c++SOCKET udpSocket;udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if (udpSocket == INVALID_SOCKET)std::cout << "Failed to create socket" << std::endl;WSACleanup(;return 1;```2.绑定UDP套接字设置套接字的地址和端口号:```c++sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(1234); // 设置端口号为1234serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 使用任意可用IP地址```绑定套接字:```c++if (bind(udpSocket, (struct sockaddr*) &serverAddr,sizeof(serverAddr)) == SOCKET_ERROR)std::cout << "Failed to bind socket" << std::endl;closesocket(udpSocket);WSACleanup(;return 1;```3.接收和发送数据接收数据:```c++char buffer[1024];sockaddr_in clientAddr;int clientAddrSize = sizeof(clientAddr);int recvSize = recvfrom(udpSocket, buffer, sizeof(buffer), 0, (struct sockaddr*) &clientAddr, &clientAddrSize);if (recvSize > 0)buffer[recvSize] = '\0';std::cout << "Received data: " << buffer << std::endl;```发送数据:```c++const char* sendData = "Hello, UDP Server!";int sendSize = sendto(udpSocket, sendData, strlen(sendData), 0, (struct sockaddr*) &clientAddr, clientAddrSize);if (sendSize == SOCKET_ERROR)std::cout << "Failed to send data" << std::endl;```4.关闭套接字和释放资源```c++closesocket(udpSocket);WSACleanup(;```以上是用VC实现最简单的UDP通信的基本步骤。
VC++网络通信的两种基本方法
VC++网络通信的两种基本方法说明:主要介绍VC++中TCP,UDP通信的两种基本方法,并附上代码TCP服务器端1.在Instance函数里添加初始化函数(在StAfx.h中加入头文件:Afsock..h)AfxSocketInit();2. 网络初始化SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//创建套接字(socket)。
SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//转换Unsigned short为网络字节序的格式addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);//端口号6000bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//将套接字绑定到一个本地地址和端口上(bind)listen(sockSrv,5);//将套接字设为监听模式,准备接收客户请求(listen)。
3.接收和发送函数(此时发生阻塞,一般建立一个发送线程,把接收函数放里面)SOCKADDR_IN addrClient;//定义地址族int len=sizeof(SOCKADDR);//初始化这个参数,这个参数必须被初始化while(1){SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);accept的第三个参数一定要有初始值。
//此时程序在此发生阻塞char sendBuf[100];sprintf(sendBuf,"发送的字符串",inet_ntoa(addrClient.sin_addr));//用返回的套接字和客户端进行通信(send/recv)。
send(sockConn,sendBuf,strlen(sendBuf)+1,0);char recvBuf[100];recv(sockConn,recvBuf,100,0);printf("%s\n",recvBuf);closesocket(sockConn);//关闭套接字。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC实现最简单的UDP通信//Client端代码#include <winsock2.h>#include <iostream.h>#include <stdio.h>void initClient();int main(){initClient();return 0;}void initClient(){WSADATA wsaData;int error=WSAStartup(MAKEWORD(2,2),&wsaData);if(error!=0){cout<<"初始化DLL失败"<<endl;return;}if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2){WSACleanup();cout<<"版本出错"<<endl;return;}SOCKET s=socket(AF_INET,SOCK_DGRAM,0);SOCKADDR_IN sockSend;sockSend.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");sockSend.sin_port=htons(4000);sockSend.sin_family=AF_INET;char buff[1024];strcpy(buff,"hello,it's the first!");int i=500;while(--i){int lenword;lenword=sendto(s,buff,strlen(buff)+1,0,(sockaddr*)&sockSend,sizeof(sockaddr));cout<<lenword<<","<<sockSend.sin_port<<":"<<sockSend.sin_addr.S_un.S _addr<<endl;}closesocket(s);WSACleanup();}//Server端代码#include <winsock2.h>#include <iostream>#include <stdio.h>using namespace std;void initNet();int main(){initNet();return 0;}void initNet(){WSADATA wsaData;int error=WSAStartup(MAKEWORD(1,1),&wsaData);if(error!=0){cout<<"初始化DLL失败"<<endl;return;}if(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1) {WSACleanup();cout<<"版本出错"<<endl;return;}SOCKET s=socket(AF_INET,SOCK_DGRAM,0);SOCKADDR_IN sockSrc;sockSrc.sin_addr.S_un.S_addr=htonl(INADDR_ANY);sockSrc.sin_port=htons(4000);sockSrc.sin_family=AF_INET;bind(s,(SOCKADDR *)&sockSrc,sizeof(SOCKADDR));char recBuff[1024];memset(recBuff,0,1024);SOCKADDR_IN sockRec;int len=sizeof(SOCKADDR);int x=-1;cout<<sockSrc.sin_port<<":"<<sockSrc.sin_addr.S_un.S_addr<<endl; while(x==-1){x=recvfrom(s,recBuff,sizeof(recBuff),0,(sockaddr *)&sockRec,&len);}printf("the receive is:%s,%d \n",recBuff,x);closesocket(s);WSACleanup();}程序能够运行,客户端发送的数据服务端收不道,运行时客户端和服务都再一台机器Windows 95环境下,基于TCP/IP协议,用Winsock完成了话音的一端传输摘要:在Windows 95环境下,基于TCP/IP协议,用Winsock完成了话音的端到端传输。
采用双套接字技术,阐述了主要函数的使用要点,以及基于异步选择机制的应用方法。
同时,给出了相应的实例程序。
一、引言Windows 95作为微机的操作系统,已经完全融入了网络与通信功能,不仅可以建立纯Windows 95环境下的“对等网络”,而且支持多种协议,如TCP/IP、IPX/SPX、NETBUI 等。
在TCP/IP协议组中,TPC是一种面向连接的协义,为用户提供可靠的、全双工的字节流服务,具有确认、流控制、多路复用和同步等功能,适于数据传输。
UDP协议则是无连接的,每个分组都携带完整的目的地址,各分组在系统中独立传送。
它不能保证分组的先后顺序,不进行分组出错的恢复与重传,因此不保证传输的可靠性,但是,它提供高传输效率的数据报服务,适于实时的语音、图像传输、广播消息等网络传输。
Winsock接口为进程间通信提供了一种新的手段,它不但能用于同一机器中的进程之间通信,而且支持网络通信功能。
随着Windows 95的推出。
Winsock已经被正式集成到了Windows系统中,同时包括了16位和32位的编程接口。
而Winsock的开发工具也可以在Borland C++4.0、Visual C++2.0这些C编译器中找到,主要由一个名为winsock.h 的头文件和动态连接库winsock.dll或wsodk32.dll组成,这两种动态连接库分别用于Win16和Win32的应用程序。
本文针对话音的全双工传输要求,采用UDP协议实现了实时网络通信。
使用VisualC++2.0编译环境,其动态连接库名为wsock32.dll。
二、主要函数的使用要点通过建立双套接字,可以很方便地实现全双工网络通信。
1.套接字建立函数:SOCKET socket(int family,int type,int protocol)对于UDP协议,写为:SOCKRET s;s=socket(AF_INET,SOCK_DGRAM,0);或s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)为了建立两个套接字,必须实现地址的重复绑定,即,当一个套接字已经绑定到某本地地址后,为了让另一个套接字重复使用该地址,必须为调用bind()函数绑定第二个套接字之前,通过函数setsockopt()为该套接字设置SO_REUSEADDR套接字选项。
通过函数getsockopt()可获得套接字选项设置状态。
需要注意的是,两个套接字所对应的端口号不能相同。
此外,还涉及到套接字缓冲区的设置问题,按规定,每个区的设置范围是:不小于512个字节,大大于8k字节,根据需要,文中选用了4k字节。
2.套接字绑定函数int bind(SOCKET s,struct sockaddr_in*name,int namelen)s是刚才创建好的套接字,name指向描述通讯对象的结构体的指针,namelen是该结构体的长度。
该结构体中的分量包括:IP地址(对应name.sin_addr.s_addr)、端口号(name.sin_port)、地址类型(name.sin_family,一般都赋成AF_INET,表示是internet 地址)。
(1)IP地址的填写方法:在全双工通信中,要把用户名对应的点分表示法地址转换成32位长整数格式的IP地址,使用inet_addr()函数。
(2)端口号是用于表示同一台计算机不同的进程(应用程序),其分配方法有两种:1)进程可以让系统为套接字自动分配一端口号,只要在调用bind前将端口号指定为0即可。
由系统自动分配的端口号位于1024~5000之间,而1~1023之间的任一TCP或UDP端口都是保留的,系统不允许任一进程使用保留端口,除非其有效用户ID是零(超级用户)。
2)进程可为套接字指定一特定端口。
这对于需要给套接字分配一众所端口的服务器是很有用的。
指定范围为1024和65536之间。
可任意指定。
在本程序中,对两个套接字的端口号规定为2000和2001,前者对应发送套接字,后者对应接收套接字。
端口号要从一个16位无符号数(u_short类型数)从主机字节顺序转换成网络字节顺序,使用htons()函数。
根据以上两个函数,可以给出双套接字建立与绑定的程序片断。
//设置有关的全局变量SOCKET sr,ss;HPSTR sockBufferS,sockBufferR;HANDLE hSendData,hReceiveData;DWROD dwDataSize=1024*4;struct sockaddr_in therel.there2;#DEFINE LOCAL_HOST_ADDR 200.200.200.201#DEFINE REMOTE_HOST-ADDR 200.200.200.202#DEFINE LOCAL_HOST_PORT 2000#DEFINE LOCAL_HOST_PORT 2001//套接字建立函数BOOL make_skt(HWND hwnd){struct sockaddr_in here,here1;ss=socket(AF_INET,SOCK_DGRAM,0);sr=socket(AF_INET,SOCK_DGRAM,0);if((ss==INVALID_SOCKET)||(sr==INVALID_SOCKET)){MessageBox(hwnd,“套接字建立失败!”,“”,MB_OK);return(FALSE);}here.sin_family=AF_INET;here.sin_addr.s_addr=inet_addr(LOCAL_HOST_ADDR);here.sin_port=htons(LICAL_HOST_PORT);//another socketherel.sin_family=AF_INET;herel.sin_addr.s_addr(LOCAL_HOST_ADDR);herel.sin_port=htons(LOCAL_HOST_PORT1);SocketBuffer();//套接字缓冲区的锁定设置setsockopt(ss,SOL_SOCKET,SO_SNDBUF,(char FAR*)sockBufferS,dwDataSize); if(bind(ss,(LPSOCKADDR)&here,sizeof(here))){MessageBox(hwnd,“发送套接字绑定失败!”,“”,MB_OK);return(FALSE);}setsockopt(sr SQL_SOCKET,SO_RCVBUF|SO_REUSEADDR,(char FAR*) sockBufferR,dwDataSize);if(bind(sr,(LPSOCKADDR)&here1,sizeof(here1))){MessageBox(hwnd,“接收套接字绑定失败!”,“”,MB_OK);return(FALSE);}return(TRUE);}//套接字缓冲区设置void sockBuffer(void){hSendData=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,dwDataSize);if(!hSendData){MessageBox(hwnd,“发送套接字缓冲区定位失败!”,NULL,MB_OK|MB_ICONEXCLAMATION);return;}if((sockBufferS=GlobalLock(hSendData)==NULL){MessageBox(hwnd,“发送套接字缓冲区锁定失败!”,NULL,MB_OK|MB_ICONEXCLAMATION);GlobalFree(hRecordData[0];return;}hReceiveData=globalAlloc(GMEM_MOVEABLE|GMEM_SHARE,dwDataSize);if(!hReceiveData){MessageBox(hwnd,"“接收套接字缓冲区定位败!”,NULLMB_OK|MB_ICONEXCLAMATION);return;}if((sockBufferT=Globallock(hReceiveData))=NULL)MessageBox(hwnd,"发送套接字缓冲区锁定失败!”,NULL,MB_OK|MB_ICONEXCLAMATION);GlobalFree(hRecordData[0]);return;}{3.数据发送与接收函数;int sendto(SOCKET s.char*buf,int len,int flags,struct sockaddr_in to,int tolen);int recvfrom(SOCKET s.char*buf,int len,int flags,struct sockaddr_infron,int*fromlen)其中,参数flags一般取0。