📄 os_socket.c
字号:
#include <stdio.h>
#include "os_defs.h"
#include "os_socket.h"
OS_STATUS OS_OpenSocketServer(OS_SOCKET * p_sock, int prot_type,OS_SOCKET_PORT server_port)
{
//第1.定义两个ipv4 地址,
struct sockaddr_in server_addr;
int val;
if(p_sock == NULL)
return OS_NOT_FOUND;
//第一步:建立TCP套接字 Socket
// AF_INET --> ip通讯
// SOCK_STREAM -->TCP
if((*p_sock = socket(AF_INET,prot_type,0))==INVALID_SOCKET) {
return OS_ERROR;
}
/* 重用服务器地址 */
val = 1;
setsockopt(*p_sock, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof (val));
//第二步:设置侦听端口
//初始化结构体,并绑定端口
server_addr.sin_family = AF_INET; /* ipv4 */
server_addr.sin_port = htons(server_port); /* 设置侦听端口是 2323 , 用htons转成网络序*/
server_addr.sin_addr.s_addr = INADDR_ANY; /* INADDR_ANY来表示任意IP地址可能其通讯 */
memset(&(server_addr.sin_zero), 0,8);
//第三步:绑定套接口,把socket队列与端口关联起来.
if(bind(*p_sock,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))==SOCKET_ERROR)
{
return OS_ERROR;
}
if(prot_type == SOCK_STREAM)
{
//第四步:开始在端口侦听,是否有客户端发来联接
if(listen(*p_sock,10)==SOCKET_ERROR)
return OS_ERROR;
}
return OS_OK;
}
OS_STATUS OS_OpenSocketClient(OS_SOCKET * p_sock,int prot_type,char * server_addr,OS_SOCKET_PORT server_port ,OS_SOCKET_PORT client_port)
{
struct sockaddr_in remote_addr;
OS_SOCKET sock;
if(p_sock == NULL)
return OS_NOT_FOUND;
//第一步:建立一个套接字
if((sock = socket(AF_INET,prot_type,0))==INVALID_SOCKET) {
return OS_ERROR;
}
if(client_port != OS_ANY_PORT)
{
struct sockaddr_in client_addr;
client_addr.sin_family = AF_INET; /* host byte order */
client_addr.sin_port = htons(client_port); /* short, network byte order */
client_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
/* 跟某个端口绑定 */
if (bind(sock, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
OS_SocketClose(sock);
return OS_ERROR;
}
}
//第三步:用connect 和服务器建立连接 ,
//注意,这里没有使用本地端口,将由协议栈自动分配一个端口
if(prot_type == SOCK_STREAM)
{
//第二步:设置服务器地址和端口
//
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(server_port);
remote_addr.sin_addr.s_addr = inet_addr(server_addr);
memset(&(remote_addr.sin_zero), 0,8);
if(connect(sock,(struct sockaddr *)&remote_addr, sizeof(struct sockaddr))==SOCKET_ERROR)
{
OS_SocketClose(sock);
return OS_ERROR;
}
}
*p_sock = sock;
return OS_OK;
}
OS_STATUS OS_OpenUDPBroadCast(OS_SOCKET * p_sock,OS_SOCKET_PORT bind_port)
{
struct sockaddr_in client_addr;
OS_SOCKET sock;
int bBroadcast=1;
if(p_sock == NULL)
return OS_NOT_FOUND;
*p_sock = INVALID_SOCKET;
//第一步:建立一个套接字
if((sock = socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET) {
return OS_ERROR;
}
//设置可以发送广播包
setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(int));
if(bind_port)
{
client_addr.sin_family = AF_INET; /* host byte order */
client_addr.sin_port = htons(bind_port); /* short, network byte order */
client_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
/* 跟某个端口绑定 */
if (bind(sock, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
OS_SocketClose(sock);
return OS_ERROR;
}
}
*p_sock = sock;
return OS_OK;
}
OS_STATUS OS_SendUDP(OS_SOCKET sock,char * addr,OS_SOCKET_PORT port,char * buffer,int len)
{
struct sockaddr_in peer_addr;
peer_addr.sin_family = AF_INET; /* host byte order */
peer_addr.sin_port = htons(port); /* short, network byte order */
if(addr == NULL)
peer_addr.sin_addr.s_addr = INADDR_BROADCAST; /* auto-fill with my IP */
else
peer_addr.sin_addr.s_addr = inet_addr(addr);
return sendto(sock,buffer,len,0,(struct sockaddr *)&peer_addr,sizeof(struct sockaddr_in));
}
OS_IPV4_ADDR OS_GetPeerAddr(OS_SOCKET sock)
{
struct sockaddr_in peer_addr;
int addr_len;
unsigned long peer_ip_addr;
addr_len = sizeof(peer_addr);
peer_ip_addr = 0;
if (OS_OK == getpeername(sock, (struct sockaddr *)&peer_addr, &addr_len))
peer_ip_addr = peer_addr.sin_addr.s_addr;
return peer_ip_addr;
}
OS_IPV4_ADDR OS_GetLocalAddr()
{
char host_name[512];
unsigned long host_ip;
if (-1 != gethostname(host_name, sizeof(host_name)))
{
struct hostent *host_ent;
host_ent = gethostbyname ( host_name );
if (host_ent == NULL)
return 0;
memcpy(&(host_ip), host_ent->h_addr,sizeof(host_ip));
return host_ip;
}
return 0;
}
#if (__OS_TYPE__ == __OS_WIN32__)
OS_STATUS Win32GetIpByHost(char * host_name,char * ip_addr,int ip_len)
{
struct sockaddr_in dest;
struct hostent *hp = NULL;
memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
/* 首先假设是一个点分形式IP地址,用转换函数转换一次*/
if ((dest.sin_addr.s_addr = inet_addr(host_name)) != INADDR_NONE)
{ /* 如果成功,直接IP地址转换回去,多余空格,0字符将被去掉*/
snprintf(ip_addr,ip_len,"%s", inet_ntoa(dest.sin_addr));
return (OS_OK);
}
/* 然后假设是一个域名,尝试转换一次*/
if ((hp = gethostbyname(host_name)) != NULL)
{
memcpy(&(dest.sin_addr), hp->h_addr, hp->h_length);
dest.sin_family = hp->h_addrtype;
snprintf(ip_addr,ip_len,"%s", inet_ntoa(dest.sin_addr));
return OS_OK;
}
return OS_ERROR;
}
#elif (__OS_TYPE__ == __OS_LINUX__)
OS_STATUS LinuxGetIpByHost(char * host_name,char * ip_addr,int ip_len)
{
struct sockaddr_in addr;
struct hostent *host;
char **alias;
/* 这里我们先假设是IP,通过IP获得主机信息*/
if(inet_aton(host_name,&(addr.sin_addr))!=0)
{ /* 如果成功,重新以点分字符串形式,写到返回BUFFER*/
snprintf(ip_addr,ip_len,"%s", inet_ntoa(addr.sin_addr));
return OS_OK;
}
/* 如果转换不成功,把host_name域名来查找一次,通过域名找主机信息*/
host=gethostbyname(host_name);
/* 查询域名失败,可能是输入错误地址,返回*/
if(host == NULL)
return OS_ERROR;
/* 查询结果可能存有多IP地址,即一个域名可能对应多个IP,一般采用第一个*/
alias=host->h_addr_list;
if(alias == NULL)
return OS_NOT_FOUND;
/* 以点分字符串形式返回*/
snprintf(ip_addr,ip_len,"%s",inet_ntoa(*(struct in_addr *)(*alias)));
return (OS_OK);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -