[code=cpp] #include<Winsock2.h> #include<stdio.h> //需要在Project->Settings->Link->Object/librarymodules中加入ws2_32.lib void main() { WORD wVersionRequested; WSADATA wsaData; wVersionRequested=MAKEWORD(2,2); if(WSAStartup(wVersionRequested,&wsaData)!=0)//初始化ws2_32.dll动态库 { printf("WSAStartup()failed!\n");//Winsock初始化错误 exit(-1); } if(wsaData.wVersion!=wVersionRequested) { printf("Theversion of Winsock is not suited!\n");//Winsock版本不匹配 WSACleanup();//结束对ws2_32.dll的调用 exit(-1); } //说明ws2_32.dll正确加载 printf("Loadws2_32.dll successfully!\n"); } 代码 #include<windows.h> #include<windowsx.h> #include"main.h" #include"dialogs.h" #include"resource.h" #include"winsock2.h" BOOL WINAPIMain_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { /* BEGIN MESSAGE CRACK */ HANDLE_MSG(hWnd, WM_INITDIALOG,Main_OnInitDialog); HANDLE_MSG(hWnd, WM_COMMAND,Main_OnCommand); HANDLE_MSG(hWnd,WM_CLOSE,Main_OnClose); /* END MESSAGE CRACK */ } return FALSE; } /******************************************************************************* * Main_OnInitDialog */ BOOLMain_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { /* Set app icons */ HICON hIcon = LoadIcon((HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE) ,MAKEINTRESOURCE(IDI_ICONAPP)); SendMessage(hwnd, WM_SETICON, TRUE, (LPARAM)hIcon); SendMessage(hwnd, WM_SETICON, FALSE,(LPARAM)hIcon); /* * Add initializing code here */ return TRUE; } /******************************************************************************* * Main_OnCommand */ voidMain_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { switch(id) { case IDC_OK: SocketTest(hwnd); break; case IDC_CANCEL: MessageBox(hwnd,TEXT("Youclicked Cancel!"),TEXT("socket"),MB_OK); EndDialog(hwnd, id); break; default:break; } } /******************************************************************************* * Main_OnClose */ void Main_OnClose(HWNDhwnd) { EndDialog(hwnd, 0); } void SocketTest(HWNDhwnd) { WSADATAwsaData; WSAStartup(MAKEWORD(2,0),&wsaData); //初始化socket //创建socket SOCKETsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKADDR_IN sa; sa.sin_family= AF_INET; sa.sin_port= htons(IPPORT_SMTP); sa.sin_addr.S_un.S_addr= inet_addr("123.125.50.138"); if( connect(sock, (SOCKADDR *)&sa,sizeof(sa)) == SOCKET_ERROR) { ShowError(); return; } char buffer[256]; ZeroMemory(buffer,sizeof(buffer)/sizeof(char)); recv(sock,buffer,256,0); MessageBox(hwnd,buffer,"",0); char sBuffer[]="QUIT\n"; send(sock,sBuffer,lstrlen(sBuffer),0); ZeroMemory(buffer,sizeof(buffer)/sizeof(char)); recv(sock,buffer,256,0); MessageBox(hwnd,buffer,"",0); closesocket(sock); WSACleanup(); } void ShowError() { TCHAR*IpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL,GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPTSTR)&IpMsgBuf, 0, NULL ); MessageBox(NULL,IpMsgBuf,"",MB_ICONERROR); } [/code]
一个完整的网络通信需要一个五元组来标识:协议、本地地址、本地端口号、远端地址、远端端口号。完整的网间通信进程需要由两个进程组成,并且只能用同一种高层协议。也就是说,不可能通信的一端用TCP,而另一端用UDP。
Socket通信的两种模式
面向连接的
面向连接的socket操作就像一部电话,他们必须建立一个连接,并由一人呼叫。所有的事情在到达时的顺序与它们出发时的顺序是一样的。面向连接的操作使用TCP协议.这个模式下的socket必须在发送数据之前与目的地的socket取得一个连接.一旦连接建立了,socket就可以使用一个流接口:打开-读-写-关闭.所有的发送的信息都会在另一端以同样的顺序被接收.面向连接的操作比无连接的操作效率低,但是数据的安全性更高.
TCP是Transfer ControlProtocol的简称,是一种面向连接的保证可靠的传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接受方的,成对的两个Socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个Socket(通常是Serversocket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或操作。因为要安全可靠相对的要付出一定代价,传输效率不如UDP高。
无连接的
无连接的socket操作就像是一个邮件投递,,没有什么保证,多个邮件可能在到达时的顺序与出发时的顺序不一样。无连接的操作使用数据报(UDP)协议.一个数据报是一个独立的单元,它包含了所有的这次投递的信息.把它想象成一个信封吧,它有目的地址和要发送的内容这个模式下的socket不需要连接一个目的地socket,它只是简单地投出数据报.无连接的操作是快速的和高效的,但是数据安全性不佳.
UDP是User DatagramProtocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。这样的特性决定了那些不要求音频视频数据绝对正确,只要保证连贯性即可的场合。
端口与地址
在网络上,一个Socket的标识主要借助于地址和端口来描述。
地址指该套接字所在计算机的网络地址,可以为域名或IP地址的形式。同一机器上可以运行多个网络应用程序,每个应用程序都有自己的套接字用以进行网络通信,此时如果只有地址标识套接字,则当一个通信包到达机器时,将无法确定究竟是哪个应用程序的套接字需要接收此信息。由此增加了端口的概念,以协助区分同一机器上不同应用程序的套接字
端口用于标识进程,同一机器上不同的网络应用程序各有不同的端口,这样,通过“网络地址+端口号”的标识方法,便唯一标识了机器上的应用程序了。某些端口是专门为公共服务保留的(Ftp:21,http:80),除非程序是要提供这些服务,否则应尽量避免使用这些端口。端口1024以前的端口号都是系统保留的或是作为公共服务的,应尽量选择大于1024的端口号,以避免冲突。
Socket通信过程
1.服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户端的连接请求。
2.客户程序根据服务器程序所在的主机名和端口号发出连接请求
3.如果一切正常,服务器接受连接请求,并获得一个新的绑定到不同端口地址的套接字
4.客户端和服务器端通过读、写套接字进行通讯。
网络连接函数
socket 创建套接字
bind 绑定本机端口
connect 建立连接
listen 监听端口
accept 接受连接
recv, recvfrom 数据接收
send, sendto 数据发送
close, shutdown 关闭套接字
SOCKET socket(
int af,//地址族,一般是AF_INET,表示使用IP地址族
int type,//socket类型,SOCK_STREAM或SOCK_DGRAM
int protocol//协议类型,通常取值0
);
Winsock中使用sockaddr_in结构指定IP地址和端口信息
struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addrsin_addr;
char sin_zero[8];
}
sin_family一般为AF_INET,表示使用IP地址族;sin_port是以网络字节序表示的16位端口号;sin_addr是网络字节序的32位IP地址;sin_zero字段一般不用,用0填充
int connect(
SOCKET s,//将要连接的socket
const structsockaddr FAR * name, //目标socket地址
int namelen//地址参数(name)的长度
);
int send(
SOCKET s,
const char FAR * buf,//发送数据缓冲区
int len, //缓冲区长度
int flags//用于控制数据传输方式,0表示按正常方式发送数据
);
返回值:发送的字节数
int recv(
SOCKET s,
char FAR * buf,//接收数据缓冲区
int len, //缓冲区长度
int flags //0表示接收的是正常数据,无特殊行为
);
返回值:接收到的字节数
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
wVersionRequested是一个WORD型(双字节型)数值,指定使用的版本号,对Winsock2.2而言,此参数的值为0x0202,也可以用宏MAKEWORD(2,2)来获得
lpWSAData是一个指向WSADATA结构的指针,它返回关于Winsock实现的详细信息
顶一下吧O(∩_∩)O谢谢支持