socket把网络协议用C语言封装成一个个函数,放到dll,供其他语言调用,
阻塞,一个函数在没有返回之前,程序被挂起.
在使用QT IDE时,如果引用第三方库,加入LIBS+=(使用库的名字)
recvfrom阻塞:
udp.h:
#ifndef UDP_H
#define UDP_H
extern "C"
{
int socket_send(const char *IP);
int socket_recv();
}//明确的告诉C++编译器,这是一个用C语言编译的函数,就不要再把函数名转换为C++格式。
//C++代码的函数在编译之后,
#endif // UDP_H
main.cpp:
#include <iostream>
#include "udp.h"
using namespace std;
int main(int argc,char *args[])//第一个数组,第二个数组
{
if(argc>1)
{
socket_send(args[1]);
}
else
socket_recv();
return 0;
system("pause");
}
udp.c:
#include <winsock2.h>
#include <string.h>
#include <stdio.h>
int socket_send(const char *IP)//使用socket网络接口,第一步需要初始化socket接口
{
DWORD ver;//相当于无符号整数
WSADATA wsaData; //WSADATA为一个结构体
ver=MAKEWORD(1,1);//在调用WSAStatrtup告诉Windows,我使用什么版本的socket
WSAStartup(ver,&wsaData);//只要用socket,第一步必须调用该函数
//初始化socket完成,固定格式
SOCKET st=socket(AF_INET,SOCK_DGRAM,0);//SOCKET为变量类型一个指向无符号整数的指针,socket为函数
//socket第一个参数指定socket用那个协议,AF_INET为tcp/ip协议
//第二个参数SOCK_DGRAM:使用UDP协议。
//第三个参数一般默认填0.
//建立一个socket
//IP地址在电脑内部,为一个整数,使用特殊的结构存储。
struct sockaddr_in addr;//sockaddr_in可以表示tcp/ip协议族里的任何一种ip地址
memset(&addr,0,sizeof(addr)); //结构体在函数参数中,被调用,应该使用取地址符"&".
addr.sin_family=AF_INET;//代表使用一个TCP/IP的地址
addr.sin_port=htons(8080);//host(主机)to net short把主机代表的数转换为short型网络的一字节
addr.sin_addr.s_addr=inet_addr(IP);//
//unsigned long laddr=inet_addr("192.168.6.200");
//printf("%x\n",sizeof(laddr));//"%x"十六进制输出
//unsigned char *p=&laddr;
//printf("%u.%u.%u.%u\n",*(p),*(p+1),*(p+2),*(p+3));
//y以上三行将IP地址转化为数组指针,然后输出IP地址。
//网络编程时的小窍门先给自己发消息,如果自己的消息可以收到,代表程序没问题。在紧接着给别的主机发消息,如果别的主机收不到消息,代表是别的主机或者网线交换器出现问题
char buf[1024]={0};
size_t rc=0;
while(1)
{
memset(buf,0,sizeof (buf));
gets(buf);
if(buf[0]=='0')
break;
//发送UDP
size_t rc=sendto(st,buf,strlen(buf),0,(struct sockaddr *)&addr,sizeof (addr));
}
closesocket(st);//使用完socket要将其关闭
WSACleanup();//释放win socket内部的相关资源
return rc;
}
int socket_recv()
{
DWORD ver;//相当于无符号整数
WSADATA wsaData; //WSADATA为一个结构体
ver=MAKEWORD(1,1);//在调用WSAStatrtup告诉Windows,我使用什么版本的socket
WSAStartup(ver,&wsaData);//只要用socket,第一步必须调用该函数
//初始化socket完成,固定格式
SOCKET st=socket(AF_INET,SOCK_DGRAM,0);//SOCKET为变量类型一个指向无符号整数的指针,socket为函数
//socket第一个参数指定socket用那个协议,AF_INET为tcp/ip协议
//第二个参数SOCK_DGRAM:使用UDP协议。
//第三个参数一般默认填0.
//建立一个socket
//IP地址在电脑内部,为一个整数,使用特殊的结构存储。
struct sockaddr_in addr;//sockaddr_in可以表示tcp/ip协议族里的任何一种ip地址
memset(&addr,0,sizeof(addr)); //结构体在函数参数中,被调用,应该使用取地址符"&".
addr.sin_family=AF_INET;//代表使用一个TCP/IP的地址
addr.sin_port=htons(8080);//host(主机)to net short把主机代表的数转换为short型网络的一字节
addr.sin_addr.s_addr=htonl(INADDR_ANY);//作为接收方,不需要指定具体的IP地址,接受的主机是什么IP,我就在什么IP上收数据。
int rc=0;
if(bind(st,(struct sockaddr *)&addr,sizeof (addr))>-1)
{
//程序与端口号绑定,接收方必须的操作
//绑定会出现绑定失败。对于OS来说,一定要避免两个程序同时绑定在同一个端口
char buf[1024]={0};
struct sockaddr_in sendaddr;
memset(&sendaddr,0,sizeof (sendaddr));
int len=sizeof (sendaddr);
while (1)
{
memset(buf,0,sizeof (buf));
//接受UDP
rc=recvfrom(st,buf,sizeof (buf),0,(struct sockaddr *)&sendaddr,&len);
//inet_ntoa(sendaddr.sin_addr);//不可重入函数
printf("%s\n",inet_ntoa(sendaddr.sin_addr),buf);
}
}
closesocket(st);//使用完socket要将其关闭
WSACleanup();//释放win socket内部的相关资源
return rc;
}
先运行收消息文件,在运行发消息文件。先将收消息文件挂起,然后接受发消息