tcp,udp

tcp udp

区别

  • tcp是面向连接的,udp无连接的协议

  • tcp是可靠的有序的

  • udp是高速的

  • 首部大小不同,udp8个字节,tcp20个字节

  • udp没有拥塞控制

  • tcp:流模式,udp:数据包模式

  • 应用:udp:游戏下载

udp

client

#include "stdafx.h"
#include "Winsock2.h"
#include "stdio.h"
#include "windows.h"
//没有下面这句,所有的通讯函数都将报错
#pragma comment(lib,"ws2_32.lib")//必须链接这个库
#define recvAddr "10.185.32.235" 
 
//发送端程序
void main()
{	//初始化socket库
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD( 1, 1 );
	// 下面的函数是连接应用程序与winsock.dll的第一个调用.
	// 第一个参数是WINSOCK 版本号,第二个参数是指向WSADATA的指针.
	// 该函数返回一个INT型值,通过检查这个值来确定初始化是否成功
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) 
	{
		printf("WSAStartup错误!!!!"); 
		system("pause");	
		return;
	}
	if ( LOBYTE( wsaData.wVersion ) != 1  ||  HIBYTE( wsaData.wVersion ) != 1 ) 
	{	WSACleanup( );
		return; 
	}
 
	SOCKET sockClient = socket( AF_INET , SOCK_DGRAM , 0 ) ;//建立socket,设置采用UDP方式通信
 
	SOCKADDR_IN addrSrv ;				//本机接收信息时,对方的IP地址,不设置时所有IP地址发送过来的信息都会被接收到
	addrSrv.sin_addr.S_un.S_addr =inet_addr(recvAddr) ;//远程主机的IP地址,127是本机的回送地址,实际没有任何网络传输
	addrSrv.sin_family = AF_INET ;
	addrSrv.sin_port = htons(1234) ;//远程主机的端口port
 
	char sendBuf[10]="" ;
	char recvBuf[50]="" ;
	char tempBuf[50]="" ;
 
	int len = sizeof(SOCKADDR) ;
 
	int a=100,b=0,c=0;
	char a1[3],b1[3]c1[3];
	while (1)
	{	
		itoa(a,a1,10);
		itoa(b,b1,10);
		itoa(c,c1,10);
		_snprintf(sendBuf,9, "%3s%3s%3s",a1,b1,c1 );//将a1,b1,c1按第三个形参的格式生成一个char型数组,并将第三个形参char数组中的前9个元素写入senBuf数组的前九个位置
		sendBuf[9]='0';
		sendto( sockClient , sendBuf , 10 , 0 , (SOCKADDR*)&addrSrv , len ) ;//发送10个char数组
		
		for(int i =0;i<50;i++)
		{
			tempBuf[i]=' ';
		}
		printf( "send\n" ) ;
		if(b<100)
		{
		b+=1;
		if(a>20)
		b=a-15;
		else if(b>10)
		c=b-10;
		else if(tested>5)
		c=b-5;
		}
		else
		{
			a=100,b=0,c=0;
		}
		Sleep(1000);
 
	}
 
	closesocket(sockClient) ;//关闭socket
	WSACleanup() ;
}
server

#include "stdafx.h"
#include "Winsock2.h"
#include "stdio.h"
#include "windows.h"
#pragma comment(lib,"ws2_32.lib") //没有下面这句,所有的通讯函数都将报错
 
void main()
{	//初始化socket库
	WORD wVersionRequested;
	WSADATA wsaData; //wsaData用来存储系统传回的关于WINSOCK的资料
	int err;
	wVersionRequested = MAKEWORD( 1, 1 );
 
	// 下面的函数是连接应用程序与winsock.dll的第一个调用.
	// 第一个参数是WINSOCK 版本号,第二个参数是指向WSADATA的指针.
	// 该函数返回一个INT型值,通过检查这个值来确定初始化是否成功
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) return;
	if ( LOBYTE( wsaData.wVersion ) != 1 ||  HIBYTE( wsaData.wVersion ) != 1 ) 
	{	WSACleanup( );
		return; 
	}
	SOCKET sockSrv = socket( AF_INET , SOCK_DGRAM , 0 ) ;
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr =inet_addr("10.185.32.235");
	addrSrv.sin_family = AF_INET ,
	addrSrv.sin_port = htons(1000) ;
 
	bind( sockSrv , (SOCKADDR*)&addrSrv , sizeof(SOCKADDR) ) ;//将SOCKET和指定的IP地址端口绑定在一起,本SOCKET就用第二个形参设定好的IP端口和其他主机进行通信
 
	char sendBuf[100]="received" ;
	char recvBuf[100]="" ;
	char tempBuf[200]="" ;
 
	SOCKADDR_IN addrClient ;//这里没有设置IP地址,所以所有的IP发的UDP信息都会被本机接收到
	int len = sizeof(SOCKADDR) ;
 
	while (1)
	{
	recvfrom(sockSrv,recvBuf,9,0,(SOCKADDR*)&addrClient,&len) ;//接收9个char型字符并赋值给recvBuf数组的前九个元素
	_snprintf(tempBuf,24,"%s say: %s\n",inet_ntoa(addrClient.sin_addr),recvBuf) ;
	for(int i =0;i<50;i++)
	{
		tempBuf[i]=' ';
		recvBuf[i]=' ';
	}
	sendto(sockSrv,sendBuf,9,0,(SOCKADDR*)&addrClient,len) ;
	}
	closesocket( sockSrv ) ;
	WSACleanup() ;
	}

tcp

client:
#include "pch.h"
#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
void initialization();
int main() {
	//定义长度变量
	int send_len = 0;
	int recv_len = 0;
	//定义发送缓冲区和接受缓冲区
	char send_buf[100];
	char recv_buf[100];
	//定义服务端套接字,接受请求套接字
	SOCKET s_server;
	//服务端地址客户端地址
	SOCKADDR_IN server_addr;
	initialization();
	//填充服务端信息
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	server_addr.sin_port = htons(1234);
	//创建套接字
	s_server = socket(AF_INET, SOCK_STREAM, 0);
	if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		cout << "服务器连接失败!" << endl;
		WSACleanup();
	}
	else {
		cout << "服务器连接成功!" << endl;
	}
 
	//发送,接收数据
	while (1) {
		cout << "请输入发送信息:";
		cin >> send_buf;
		send_len = send(s_server, send_buf, 100, 0);
		if (send_len < 0) {
			cout << "发送失败!" << endl;
			break;
		}
		recv_len = recv(s_server, recv_buf, 100, 0);
		if (recv_len < 0) {
			cout << "接受失败!" << endl;
			break;
		}
		else {
			cout << "服务端信息:" << recv_buf << endl;
		}
 
	}
	//关闭套接字
	closesocket(s_server);
	//释放DLL资源
	WSACleanup();
	return 0;
}
void initialization() {
	//初始化套接字库
	WORD w_req = MAKEWORD(2, 2);//版本号
	WSADATA wsadata;
	int err;
	err = WSAStartup(w_req, &wsadata);
	if (err != 0) {
		cout << "初始化套接字库失败!" << endl;
	}
	else {
		cout << "初始化套接字库成功!" << endl;
	}
	//检测版本号
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
		cout << "套接字库版本号不符!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字库版本正确!" << endl;
	}
	//填充服务端地址信息
 
}
server:
#include "pch.h"
#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
void initialization();
int main() {
	//定义长度变量
	int send_len = 0;
	int recv_len = 0;
	int len = 0;
	//定义发送缓冲区和接受缓冲区
	char send_buf[100];
	char recv_buf[100];
	//定义服务端套接字,接受请求套接字
	SOCKET s_server;
	SOCKET s_accept;
	//服务端地址客户端地址
	SOCKADDR_IN server_addr;
	SOCKADDR_IN accept_addr;
	initialization();
	//填充服务端信息
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(5010);
	//创建套接字
	s_server = socket(AF_INET, SOCK_STREAM, 0);
	if (bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		cout << "套接字绑定失败!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字绑定成功!" << endl;
	}
	//设置套接字为监听状态
	if (listen(s_server, SOMAXCONN) < 0) {
		cout << "设置监听状态失败!" << endl;
		WSACleanup();
	}
	else {
		cout << "设置监听状态成功!" << endl;
	}
	cout << "服务端正在监听连接,请稍候...." << endl;
	//接受连接请求
	len = sizeof(SOCKADDR);
	s_accept = accept(s_server, (SOCKADDR *)&accept_addr, &len);
	if (s_accept == SOCKET_ERROR) {
		cout << "连接失败!" << endl;
		WSACleanup();
		return 0;
	}
	cout << "连接建立,准备接受数据" << endl;
	//接收数据
	while (1) {
		recv_len = recv(s_accept, recv_buf, 100, 0);
		if (recv_len < 0) {
			cout << "接受失败!" << endl;
			break;
		}
		else {
			cout << "客户端信息:" << recv_buf << endl;
		}
		cout << "请输入回复信息:";
		cin >> send_buf;
		send_len = send(s_accept, send_buf, 100, 0);
		if (send_len < 0) {
			cout << "发送失败!" << endl;
			break;
		}
	}
	//关闭套接字
	closesocket(s_server);
	closesocket(s_accept);
	//释放DLL资源
	WSACleanup();
	return 0;
}
void initialization() {
	//初始化套接字库
	WORD w_req = MAKEWORD(2, 2);//版本号
	WSADATA wsadata;
	int err;
	err = WSAStartup(w_req, &wsadata);
	if (err != 0) {
		cout << "初始化套接字库失败!" << endl;
	}
	else {
		cout << "初始化套接字库成功!" << endl;
	}
	//检测版本号
	if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {
		cout << "套接字库版本号不符!" << endl;
		WSACleanup();
	}
	else {
		cout << "套接字库版本正确!" << endl;
	}
	//填充服务端地址信息
 
}

代码过程以及区别:

(1)创建套接字时,第二个参数不同

(2)tcp客户端多了一个connect的过程

(3) udp发送接受是sendto ,recvfrom tcp是 send,recv

​ 因为sendto加了目标的地址,和端口

tcp绑定后就可以不用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值