tcp与udp编程(1对1)

本文参考了以下博客内容: 

基于Linux下的TCP编程基于Linux下的UDP编程udp socket编程中的connect()

对于通信,首先需要对方的地址,这里对方的地址就是IP:port组成的套接字。

1 TCP

tcp是有连接的,所以它会在建立连接后,双方都知晓了对方的地址,可以进行通信。顺序为一端bind(),另一端
connect()。 bind()函数即为其确定了一个套接字的地址,因此通信的一方就确定了。另一方connect(),为了表述
方便,不妨称其为B ,若此时B还未确定套接字地址,则 connect()将为其 透明的分配一个套接字地址用以通信。
A方,即上述bind()方,accept()到这个连接后,同时为accept()的(struct sockaddr_in)类型的参数赋 了值。此
时,双方均知晓对方的 地址,就可以通信了。

2 UDP

udp是无连接的,因此和上述有所不同,因为我们不能通过连接来知晓对方的地址。有以下两种方式来完成,同样
假设为A,B两方。
(1)
A方:bind(),recvfrom(),sendto();
B方:sendto(),recvfrom();
无论怎样,要想通信,必须至少先确定一方的地址,因此bind()函数是必须的。此时A还不知道另一方的套接字,
所以调用recvfrom()来获取对方地址,当然, 在B调用sendto() 前,A将阻塞。 顺序就是A方recvfrom(),B方
sendto(),B方recvfrom(),A在sendto(),recvfrom()......
这其中,每次recvfrom()都是一次地址更新的过程,如果两方不停传输很多消息,显然这个地址更新很没必要。
(2)
另一种就是不使用recvfrom()函数了,这样就不会更新地址了,但是发送消息的时候我们需要地址,怎么办?
此时使用connect函数。此时,像tcp中一样,B方connect后,就可以使用recv(),send()函数了,这样B就可以
不用一直更新地址了。但是A依然需要不停的 recvfrom(),sendto() (我没那能力看源码,做实验得到的)。所以
我们容易想到让A方也connect(),但是connect()到哪个地址呢?这就需要知晓对方的地址, 需要对方确定自己
的地址,也即让B也 bind()一个地址,确定自己的套接字,这样就变成,如下
A:bind(),connect(),send(),recv().......
B:   bind(),connect(),recv(),send()............
通信方A:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define PORT 1111 /*使用的port*/
int main(){
	int sockfd,len;
	struct sockaddr_in addr,clientaddr;
	char buffer[256];
	/*建立socket*/
	if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0){
		perror ("socket");
		exit(1);
	}
	/*填写sockaddr_in 结构*/
	bzero ( &addr, sizeof(addr) );
	addr.sin_family=AF_INET;
	addr.sin_port=htons(PORT);
	addr.sin_addr.s_addr=htonl(INADDR_ANY) ;
	if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))<0){
		perror("connect");
		exit(1);
	}
	memset(&clientaddr,0,sizeof(struct sockaddr_in));
	clientaddr.sin_family = AF_INET;
	clientaddr.sin_port = htons(5555);
	clientaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	connect(sockfd,(struct sockaddr*)&clientaddr,sizeof(struct sockaddr_in));
	while(1){
		bzero(buffer,sizeof(buffer));
		len = recv(sockfd,buffer,sizeof(buffer), 0);// , (struct sockaddr *)&addr ,&addr_len);
		/*显示client端的网络地址*/
		printf("receive from %s:%d,%s\n" , inet_ntoa( addr.sin_addr),ntohs(addr.sin_port),buffer);
		/*将字串返回给client端*/
		send(sockfd,buffer,len,0);//,(struct sockaddr *)&addr,addr_len);
		printf("send complete\n");
	}
}
通信方B;
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
using namespace std;
int main()
{
	int sock = socket(AF_INET,SOCK_DGRAM,0);
	if(sock == -1)
		cout << "create socket error" << endl;

	struct sockaddr_in serveraddr,clientaddr;
	memset(&serveraddr,0,sizeof(struct sockaddr_in));
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(1111);
	serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	memset(&clientaddr,0,sizeof(struct sockaddr_in));
	clientaddr.sin_family = AF_INET;
	clientaddr.sin_port = htons(5555);
	clientaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	bind(sock,(struct sockaddr*)&clientaddr,sizeof(struct sockaddr_in));
	int rc = connect(sock,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr_in));
	if(rc == -1)
		cout << "connect error" << endl;
	char send_buff[10];
	send_buff[0] = '1';
	send_buff[1] = 0;

	//socklen_t len = sizeof(struct sockaddr_in);
	send(sock,send_buff,10,0);//,(struct sockaddr*)&serveraddr,len);
	recv(sock,send_buff,10,0);//,(struct sockaddr*)&serveraddr,&len);
	cout << "complete" << endl;
	close(sock);
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值