linux下使用udpsocket时遇到的问题

13 篇文章 0 订阅

linux下使用udpsocket时遇到的问题

关于数据报socket的使用,很多博客都有,由于事先已知客户端的ip字串,不想服务端使用通过recvfrom时保存下来的struct sockaddr_in*类型ip,想通过之前ip字串来让服务器给客户端发送数据,发现出现了问题,仔细研究后发现是发送数据给客户端时,使用了之前的服务器绑定的端口,这是不对的,客户端的端口是系统随机分配的,必须要使用之前获取客户端地址时的端口,因此必须保存该端口,其次也可以固定一个客户端端口,这样客户端需要初始化ip,同时绑定ip和端口。

具体代码如下:
客户端:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#define SERVER_PORT 8000
#define CLIENT_PORT 8001

int main()
{
	int sock_fd;
	int send_num;
	int recv_num;

	int dest_len;
	char send_buf[1024] = "hello server";
	char recv_buf[1024];

	struct sockaddr_in addr_serv;
	struct sockaddr_in addr_client;
	sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock_fd < 0)
	{
		printf("create socket failed\n");
		return -1;
	}

	//初始化本机地址
	memset(&addr_client, 0, sizeof(addr_client));
	addr_client.sin_family = AF_INET;
	addr_client.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址
	addr_client.sin_port = htons(CLIENT_PORT);
	if (bind(sock_fd, (struct sockaddr*)&addr_client, sizeof(addr_client)) < 0)
	{
		printf("client bind failed\n");
		return -1;
	}
	printf("client bind sucessful\n");

	//初始化服务端地址
	addr_serv.sin_family = AF_INET;
	addr_serv.sin_addr.s_addr = inet_addr("192.168.16.130");
	addr_serv.sin_port = htons(SERVER_PORT);

	dest_len = sizeof(struct sockaddr_in);
	printf("begin send:\n");

	send_num = sendto(sock_fd, send_buf, sizeof(send_buf), 0, (struct sockaddr*)&addr_serv, dest_len);
	if (send_num < 0)
	{
		printf("send to message fialed\n");
		return -1;
	}
	else
	{
		printf("send sucessful:%s\n",send_buf);
	}

	printf("send_num:%d\n", send_num);
	printf("client sock_id:%d\n", sock_fd);

	recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&addr_serv, &dest_len);
	printf("recvbuf:%s\n", recv_buf);
	if (recv_num < 0)
	{
		 perror("recv_from");
	}
	else
	{
		printf("recv sucessful\n");
	}

	recv_buf[recv_num]='\0';
	printf("the receive:%s\n",recv_buf);
    close(sock_fd);
	return 0;
}


服务端代码:
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <string.h>

#define SERVER_PORT 8000
#define CLIENT_PORT 8001
#define BUFF_LEN 1024

using namespace std;

int main(int argc, char* argv[])
{
	int server_fd, ret;
	struct sockaddr_in ser_addr;

	char buf[BUFF_LEN];  //接收缓冲区,1024字节
	struct sockaddr_in clent_addr;
	socklen_t len;
	int send_len;

	int count;

	char buffer[BUFF_LEN] = "fuck";  //接收缓冲区,1024字节

	server_fd = socket(AF_INET, SOCK_DGRAM, 0); //AF_INET:IPV4;SOCK_DGRAM:UDP
	if (server_fd < 0) {
		printf("create socket fail!\n");
		return -1;
	}

	/* udfServer初始化 */
	memset(&ser_addr, 0, sizeof(ser_addr));
	ser_addr.sin_family = AF_INET;
	ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址
	ser_addr.sin_port = htons(SERVER_PORT);  //端口号,需要网络序转换

	ret = bind(server_fd, (struct sockaddr*) &ser_addr, sizeof(ser_addr));
	if (ret < 0) {
		printf("socket bind fail!\n");
		return -1;
	}

	memset(buf, 0, BUFF_LEN);
	len = sizeof(clent_addr);
	ret = recvfrom(server_fd, buf, BUFF_LEN, 0, (struct sockaddr*) &clent_addr,
			&len);  //recvfrom是拥塞函数,没有数据就一直拥塞
	if (ret < 0) {
		printf("recieve data fail!\n");
	}
	printf("client:%s\n", buf);  //打印client发过来的信息
	printf("ClientIp is %4x\n", ntohl(clent_addr.sin_addr.s_addr));
	printf("%s\n", inet_ntoa(clent_addr.sin_addr));

	struct in_addr addr;
	memset(&addr, 0, sizeof(struct in_addr));
	string ip = "192.168.16.1";
	ret = inet_aton(ip.c_str(), &addr);
	if (0 > ret) {
		cout << "stringip to uint32ip is failed" << endl;
	}

	struct sockaddr_in sockClient;
	memset(&sockClient, 0, sizeof(sockaddr_in));
	sockClient.sin_family = AF_INET;
	sockClient.sin_addr.s_addr = htonl(ntohl(addr.s_addr));
	sockClient.sin_port = htons(CLIENT_PORT);

	printf("%s\n", inet_ntoa(sockClient.sin_addr));

	while (1)
	{
		send_len = sendto(server_fd, buffer, BUFF_LEN, 0,
				(struct sockaddr*) &sockClient, sizeof(sockClient));
		if (send_len < 0)
		{
			cout << "send_len:" << send_len << endl;
		}
		cout << "send_len:" << send_len << endl;
		cout << "buffer:" << buffer << endl;
	}

	close(server_fd);
	return 0;
}
测试结果如下:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值