好久没来写点东西,最近鬼事还真是多,破项目搞的人烦死。带队的经理说给我们的要求是日代码100行(核心代码),懒了这么久,一下写起来还真是累啊!
最近来了点劲头,先写上练的几个例子
使用windows套接字的网络小程序-------------------
1.Socket基本操作
(1)启动/终止
winsock在被调用时以动态链接库的形式实现,所以在它初始化时应首先调用WSAStartup函数进行初始化,同时确定被调用的winsock版本号等。
// 加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 1, 1 );
int err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return false;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return false;
这里加载了1.1版本的socket。在网络通信完成后,需要使用函数WSACleanup释放资源。
(2)创建与绑定
套接字的创建非常简单,只需要调用socket即可。如下:
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);//流式,TCP
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);//数据报,UDP
使用bind函数可以将一个套接字绑定到一个地址上
int bind(SOCKET sock, const struct sockaddr* name, int len);//sockaddr是一个用来表示地
址信息的结构
(3)侦听,接受连接与连接
listen, accept, connect这三个函数用于建立通信的连接。
int listen(SOCKET sock, int backlog);//scok必须是一个已经绑定但是没有连接的套接字,
backlog用于设定最大可以等待的连接长度
成功调用listen函数后,就可以接受客户机的连接了。
SOCKET accept(SOCKET sock, struct sockaddr* addr, int* addrlen);
到此一切就绪,当客户机想到连接时可以使用connect进行连接。
(4)发送,连接
用于TCP的:
int send(SOCKET sock, const char* buf, int len, int flags);
int recv(SOCKET sock, char* buf, int len, int flags);
用于UDP的:
int sendto(SOCKET sock, const char* buf, int len, int flags,
const struct sockaddr* to, int tolen);
int recvfrom(SOCKET sock, char* buf, int len, int flags,
struct sockaddr* from, int formlen);
2.示例
两个win32的控制台程序,一个TcpSer,一个TcpClient。
为了使用socket需要包含头文件<Winsock2.h>
TcpSer:
#include <Winsock2.h>
#include <iostream>
#include <string>
using namespace std;
void main()
{
//加载套接字库,版本1.1
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return;
}
//创建套接字
SOCKET sockSer = socket(AF_INET, SOCK_STREAM, 0);
//地址结构体
SOCKADDR_IN addrSer;
addrSer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(6000);
//绑定与监听
bind(sockSer, (SOCKADDR*)&addrSer, sizeof(SOCKADDR));
listen(sockSer, 5);
cout<<"Tcp Server Run!"<<endl;
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
//收到连接请求,创建一个新socket用于保持连接
SOCKET sockCon = accept(sockSer, (SOCKADDR*)&addrClient, &len);
while(true)
{
char recBuf[100];
recv(sockCon, recBuf, 100, 0);
cout<<"message form clinet : "<<recBuf<<endl;
}
//清理工作
closesocket(sockSer);
WSACleanup();
}
TcpClient:
#include <Winsock2.h>
#include <iostream>
#include <string>
using namespace std;
void main()
{
//加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return;
}
//创建套接字
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSer;
addrSer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(6000);
cout<<"enter your message: ";
string sendBuf;
while(cin>>sendBuf)
{
if(sendBuf == "q" || sendBuf == "Q")
break;
//连接服务器
connect(sockClient, (SOCKADDR*)&addrSer, sizeof(SOCKADDR));
send(sockClient, sendBuf.c_str(), sendBuf.length()+1, 0);
cout<<"enter your message: ";
}
//清理工作
closesocket(sockClient);
WSACleanup();
}
最后还要注意的就是:在VS下编译时还要在项目属性>配置属性>链接器>命令行里加入附加选项ws2_32.lib
否则链接的时候找不到与socket相关的函数