Udp同一个socket接收与发送实现

1、一个socket实现udp收发

socket用于udp通信时,是不区分Server与Client的。因为是无连接的,发送完了也就完了。同样接收到数据也就完成了一次通信。因此,Server端与Client端的措辞在Udp通信中的含义其实就退化了。

将socket用于tcp编程时,都比较喜欢send和recv函数。而用于udp通信编程时,个人感觉用sendto和recvfrom更方便。

因为socket用于udp通信时,如果用一种比较糙的方式实现,是无须connect操作、bind操作的。直接想要发送的时候用sendto指明接收端的参数,想要接收数据时直接用recvfrom指明发送端的参数。

2、粗糙方式

在这种粗糙的方式下,即不加任何bind、connect操作时,仅有一个缺点,也即接收时是无法指定发送方的端口。换句话说,监听的远端机器向本机任何一个端口发送数据,recvfrom都会认为收到数据了。

3、完全方式

而要Debug这个问题,添加一个bind操作即可。而且只需要bind一次。这样,需要的功能就都妥妥的了。指定远端ip的指定端口发送的数据才会触发本机recvfrom的接收。而发送功能,一直是好的。

4、代码

上一点代码。写的比较急,赶出来的。扎眼见谅啊。

1)、创建socket

//创建socket
m_sock = socket(AF_INET, SOCK_DGRAM, 0);

//设定远端地址、端口进行绑定
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_addr.S_un.S_addr = inet_addr("192.168.1.104");
addr.sin_family = AF_INET;
addr.sin_port = htonl(8889);
//绑定远端
int nRet = bind(m_sock, (sockaddr*)&addr, sizeof(addr));
TRACE("BINDRET = %d \r\n", nRet);
TRACE("errcode = %d \r\n", WSAGetLastError());

2)、发送代码

//设定目的端参数
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_addr.S_un.S_addr = inet_addr("192.168.1.104");
addr.sin_family = AF_INET;
addr.sin_port = htonl(8888);
char* buf="hehehahaheihei";
//发送数据
int sendRet=sendto(m_sock, buf, sizeof(buf), 0, (sockaddr*)&addr, sizeof(addr));
TRACE("Send errcode = %d \r\n", WSAGetLastError());
TRACE("sendRet= %d \r\n", sendRet);

3)、接收代码

//存储发送端的参数结构体,可取出ip地址端口号等
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
//接收缓冲区、参数等
char rcvBuf[20];
int len = 20;
int stSize=sizeof(addr);
int rcvRet = 0;
len = sizeof(addr);
rcvRet=recvfrom(m_sock, rcvBuf, len, 0, (sockaddr*)&addr, &stSize);
//打印出错误信息码
TRACE("rcv errcode = %d \r\n", WSAGetLastError());
TRACE("rcvRet= %d\r\n", rcvRet);

5、注意事项

1)、socket默认是阻塞的

阻塞不影响发送,因为直接发送出去立即就返回了,不管对方是否接收到。
而接收时就会阻塞了,会一直等到有数据到来。
设置为非阻塞代码

ULONG nVal = 1;
ioctlsocket(m_sock, FIONBIO, &nVal);

2)、启动函数

在创建socket之前需要调用启动函数

WSAStartup(
    WORD wVersionRequested,     //版本号
    LPWSADATA lpWSAData         //返回的参数信息。详见msdn
    );

具体调用样例如下:

WSADATA data;
WSAStartup(0X11,&data);

对称的,有一个清理函数。在退出时可以调用。有兴趣可自行了解。:)

  • 9
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值