Windows Socket的使用 总结

Windows Socket的使用简单总结

Socket的使用可以分为TCP方式、UDP方式,下面就对两种使用方式进行简单的总结

1、TCP方式

TCP方式即点对点的方式,需要建立连接之后才能进行Socket通信。

服务器端:

在建立服务器端的Socket时,服务其端需要进行:

1、初始化SOCKET运行库;

2、配置通信地址;

3、创建(socket)SOCKET;

4、绑定(bind)SOCKET地址;

5、监听(listen)SOCKET地址;

6、接受(accept)SOCKET的连接;


具体实例如下:

char name[80];
hostent* pHost;
gethostname(name,sizeof(name));//获取本机主机名
pHost = gethostbyname(name);
ip = inet_ntoa(*(struct in_addr*)pHost->h_addr_list[0]);//获取本机IP


int err;

WSADATA wsaData;
WORD wVersion;
wVersion = MAKEWORD(2,2);//生成加载的Winsock库的版本
err = WSAStartup(wVersion,&wsaData);//加载套接字库

if(err != 0){return;}

SOCKADDR_IN local_addr;
int addrsize = sizeof(SOCKADDR_IN);

local_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(5150);//绑定端口

if((listen_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{ //创建SOCKET失败   }
else
{      //创建SOCKET成功    }

if(bind(listen_sock,(struct sockaddr*)&local_addr,addrsize))
{//绑定SOCKET失败   }
else
{//绑定SOCKET失败   }

listen(listen_sock,1);//20160426 监听一个客户端

SOCKADDR_IN client_addr;//存储连接的客户端地址

SOCKET Client_Sock;//存储连接的客户端SOCKET

if((Client_Sock=accept(listen_sock,(struct sockaddr*)&client_addr,&addrsize))==INVALID_SOCKET)
{//服务器accept失败   }
else{
{ //服务器accept成功   
//port.Format("%d",int(ntohs(client_addr.sin_port)));
//("已连接来自:"+CString(inet_ntoa(client_addr.sin_addr))+"端口:"+port);
}


//接收数据

char recvMsg[1024] = {0};

int rs = -10;

rs = recv(Client_sock, recvMsg, 1024, 0);

if(rs==-1 || rs==0){//接收数据错误}

else{recvMsg[rs] = ‘\0’}


//发送数据

if(send(Client_sock, sendMsg, strlen(sendMsg),0)==SOCKET_ERROR)
{//发送失败}

客户端:

在建立客户端的Socket时,服务其端需要进行:

1、初始化SOCKET运行库;

2、配置通信地址;

3、创建(socket)SOCKET;

4、连接(connect)服务器端的地址;


具体实例如下:

WSADATA wsaData;
SOCKADDR_IN server_addr;
WORD wVersion;

wVersion = MAKEWORD(2,2);
WSAStartup(wVersion,&wsaData);

server_addr.sin_addr.S_un.S_addr = inet_addr(ip);//服务端IP
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);//服务端绑定的端口

if((sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{
printf("Error:创建SOCKET失败!\r\n");
}
else if(connect(sock,(struct sockaddr*)&server_addr,sizeof(SOCKADDR_IN))==SOCKET_ERROR)
{
printf("Error:连接服务器失败!\r\n");
}
else
{
printf(">成功连接服务器!\r\n");
}

//接收数据

char recvMsg[1024] = {0};

int rs = -10;

rs = recv(sock, recvMsg, 1024, 0);

if(rs==-1 || rs==0){//接收数据错误}

else{recvMsg[rs] = ‘\0’}

//发送数据

if(send(sock, sendMsg, strlen(sendMsg),0)==SOCKET_ERROR)
{//发送失败}

2、UDP方式

UDP的通讯方式不需要提前建立连接即可发送、接收数据。当需要数据传输时,只需要向某地址发送数据即可,

当接收方发现接收缓存区中有数据时,就会把数据读取出来。这种模式数据传输比较快,但可靠型略低,可能会造成丢包。

当采用UDP方式时,并没有严格的服务器、客户端之分;为了方便理解,可以理解为发送方、接收方。

服务器端:

在建立服务器端的Socket时,服务其端需要进行:

1、初始化SOCKET运行库;

2、配置通信地址;

3、创建(socket)SOCKET;

4、绑定(bind)接收地址;


具体实例如下:

SOCKETSockUdp;
SOCKADDR_IN recvFromAddr, serverAddr;
SOCKADDR_IN recvAddr;
SOCKADDR_IN clientUdpAddr;


WSADATA wsaData;
WORD wVersion;

wVersion = MAKEWORD(2,2);
if(WSAStartup(wVersion,&wsaData) != 0)
{
UpdateStatus("初始化SOCKET失败!");
exit(1);
}

if((SockUdp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
UpdateStatus("创建UDP-SOCKET失败!");
return;
}

// 设置该套接字为广播类型,

bool optval = true;  
    setsockopt(SockUdp, SOL_SOCKET, SO_BROADCAST, (char FAR *)&optval, sizeof(optval)); 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int addrsize = sizeof(SOCKADDR_IN);

//for send
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);//发送数据段只能以这种方式设置
serverAddr.sin_port = htons(9000);

//for receive
recvAddr.sin_family = AF_INET;
recvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
recvAddr.sin_port = htons(8000);

// 把该套接字绑定在接收地址上 
if (bind(SockUdp, (sockaddr *)&recvAddr, sizeof(recvAddr)) != 0)  
    {  
        int err = WSAGetLastError();  
UpdateStatus("bind error!");
        closesocket(SockUdp);  
        WSACleanup();  
        return;  
   

//接收数据

int res = -10;

int recvgLength=sizeof(recvFromAddr);

char recvMsg[1024] = {0};

res = recvfrom(SockUdp, recvMsg,1024, 0, (struct sockaddr FAR *)&recvFromAddr, (int FAR *)&recvgLength);
if( res == SOCKET_ERROR)
{UpdateStatus("》未正确接收数据!");
int err = WSAGetLastError(); 
break;
}
else if(res > 0)
{//数据接收成功

recvMsg[res] = ‘\0’;

}

//发送数据

int fromlength=sizeof(serverAddr);
sendto(SockUdp, s
endMsg, strlen(sendMsg), 0, (struct sockaddr FAR *)&serverAddr, fromlength);

客户端:

在建立客户端的Socket时,服务其端需要进行:

1、初始化SOCKET运行库;

2、配置通信地址;

3、创建(socket)SOCKET;

4、绑定(bind)接收地址;


具体实例如下:

WSADATA wsaData;
WORD wVersion;
wVersion = MAKEWORD(2,2);
WSAStartup(wVersion,&wsaData);

if((sock = socket(AF_INET, SOCK_DGRAM, 0))==INVALID_SOCKET)
{printf("》创建 UDP SOCKET 失败!\r\n");}


//设置该套接字为广播类型,
bool opt=true;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char FAR *)&opt, sizeof(opt));  
int nlen=sizeof(SOCKADDR_IN); 

//for receive message
//用来从网络上的广播地址接收消息
recvAddr.sin_family = AF_INET;
recvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//接收数据端可以以这种方式设置
recvAddr.sin_port = htons(9000);
//从发送端的端口9000接收数据

//bind
if (bind(sock, (SOCKADDR*)&recvAddr, sizeof(recvAddr)) != 0)  
    {  
        int err = WSAGetLastError();  
        printf("》bind error:%d\n", err);  
        closesocket(sock);  
        WSACleanup(); 
    }

//for send message
sendAddr.sin_family = AF_INET;
//sendAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
sendAddr.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);//发送数据端只能以这种方式设置
sendAddr.sin_port = htons(8000);
//向接收方的端口8000发送数据

//接收数据

int res = -10;

int recvgLength=sizeof(recvClientAddr);

char recvMsg[1024] = {0};

res = recvfrom(sock, recvMsg,1024, 0, (struct sockaddr FAR *)&recvClientAddr, (int FAR *)&recvgLength);
if( res == SOCKET_ERROR)
{ UpdateStatus("》未正确接收数据!");
int err = WSAGetLastError(); 
break;
}
else if(res > 0)
{//数据接收成功

//recvMsg[res] = ‘\0’;

}

//发送数据

int sendlength=sizeof(sendAddr);
sendto(SockUdp, s
endMsg, strlen(sendMsg), 0, (struct sockaddr FAR *)&sendAddr,sendlength);

3、备注

无论采取什么方式,都必须包含头文件: Winsock2.h

同时需要加载ws2_32.lib文件:#pragma comment(lib, "ws2_32.lib")


在创建SOCKET时。TCP方式的第二个参数为SOCK_STREAM,UDP方式的第二个参数为SOCK_DGRAM.

TCP方式下,在服务器端需要绑定地址,而对于UDP方式来说,只要接收数据,就需要绑定接收地址


猜你喜欢

转载自blog.csdn.net/bailang_zhizun/article/details/78204199