服务端:
客户端:
终于迈出了 Hello World! 的重要一步!
注意!
代码中用到的所有函数均在前5章中讲解,如有不懂的可以参考 笔记(1)至 笔记(6)。#include <winsock2.h> #include <iostream> #define PORT 5000 using namespace std; int main(void) { WSADATA wsaData; //Winsock数据结构 SOCKET ServerSocket; //服务端socket SOCKET AcceptSocket; //从客户端接收到的socket SOCKADDR_IN ServerAddr; //服务端SOCKADDR地址 SOCKADDR_IN ClientAddr; //客户端SOCKADDR地址 int port=PORT; //端口号 int ClientAddrLen; //客户区地址长度 char s[]="Hello World!"; //要传输的字符串 WSAStartup(MAKEWORD(2,2),&wsaData); //初始化 Winsock 2.2 版本 ServerSocket=socket(AF_INET,SOCK_STREAM,0); //创建一个 socket 来监听客户连接 if(ServerSocket!=INVALID_SOCKET) { cout<<"socket()创建ServerSocket成功!\n"; } else { cout<<"socket()创建ServerSocket失败!\n"<<WSAGetLastError(); } ServerAddr.sin_family=AF_INET; //填充 SOCKADDR_IN 数据结构 ServerAddr.sin_port=htons(port); ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(ServerSocket,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR) //绑定一个周知地址 { cout<<"bind()绑定周知地址失败!\n"<<WSAGetLastError(); } else { cout<<"bind()绑定周知地址成功!\n"; } if(listen(ServerSocket,5)!=SOCKET_ERROR) //设置监听模式 { cout<<"listen()监听成功!\n"; } else { cout<<"listen()监听失败!\n"; } ClientAddrLen=sizeof(ClientAddr); //显示指定ClientAddrLen大小 while(1) { AcceptSocket=accept(ServerSocket,(SOCKADDR*)&ClientAddr,&ClientAddrLen); //接受一个到来的连接,注意!最后一个参数需要自己显示指定! /* 这里你通过这些socket可以做两件事 1.通过ListeningSocket再次调用accept()来接受其他连接 2.通过NewConnection来发送/接受数据 当你做完这两件事情时必须要关闭这些socket socket的关闭将在后面介绍 */ if(INVALID_SOCKET!=AcceptSocket) { cout<<"accept()接收客户端连接成功!\n"; int sendLen=send(AcceptSocket,s,sizeof(s),0); //发送数据 if(sendLen==SOCKET_ERROR) { cout<<"send()发送数据失败!\n"<<WSAGetLastError(); } else { cout<<"send()发送数据成功!发送的字节数(实际上是拷贝到发送缓冲中的字节数):"<<sendLen; } closesocket(AcceptSocket); //关闭该连接 break; //退出循环 } } closesocket(ServerSocket); //关闭ServerSocket WSACleanup(); //关闭Winsock int nothing; //与程序无关,为了让控制台不直接关闭 cin>>nothing; return 0; }
#include <Winsock2.h> #include <iostream> #define BUFFER 1024 #define PORT 5000 using namespace std; int main(void) { WSADATA wsaData; //Winsock数据结构 SOCKET ClientSocket; //客户端socket SOCKADDR_IN ServerAddr; //服务器地址 int port=PORT; //端口号 char buf[BUFFER]; //接收的字符缓冲区 memset(buf,0,sizeof(buf)); //清空缓存 WSAStartup(MAKEWORD(2,2),&wsaData); //初始化 Winsock 2.2 版本 ClientSocket=socket(AF_INET,SOCK_STREAM,0); //创建客户端socket if(ClientSocket==INVALID_SOCKET) { cout<<"socket()创建ClientSocket失败!\n"<<WSAGetLastError(); } else { cout<<"socket()创建ClientSocket成功!\n"; } ServerAddr.sin_family=AF_INET; //填充 SOCKADDR_IN 数据结构 ServerAddr.sin_port=htons(port); ServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1"); if(connect(ClientSocket,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr))==INVALID_SOCKET) { cout<<"connect()连接服务端失败!\n"<<WSAGetLastError(); } else { cout<<"connect()连接服务端成功!\n"; } int recvLen=recv(ClientSocket,buf,sizeof(buf),0); if(recvLen==0) { cout<<"接收长度为0!\n"; } else if(recvLen==SOCKET_ERROR) { cout<<"recv()接收失败!\n"<<WSAGetLastError(); } else { cout<<"recv()接收成功!\n"<<buf<<" 接收数据字节数为:"<<recvLen; } closesocket(ClientSocket); //关闭socket WSACleanup(); //关闭Winsock int nothing; //与程序无关,为了让控制台不直接关闭 cin>>nothing; return 0; }
注意:
程序必须先运行服务端,再运行客户端,因为先要让服务端开启监听。
程序需要导入必要的库文件,详情参见 Windows网络编程学习笔记(1)。
Hello World!发送时需要算上最后一个/0结束符,因此大小是13个字节。
程序运行结果在本章最前面。