1 #include<winsock2.h>//winsock的头文件 2 #include<iostream> 3 using namespace std; 4 5 //指定动态库的lib文件 6 #pragma comment(lib,"ws2_32.lib") 7 8 //TCP服务端 9 int main() 10 { 11 12 //初始化winsock2.2相关的动态库 13 WSADATA wd;//获取socket相关信息 14 if (WSAStartup(MAKEWORD(2, 2), &wd) != 0)//0表示成功 15 { 16 cout << "WSAStartup error:"<< WSAGetLastError() << endl; 17 return 0; 18 } 19 20 //1.创建TCP socket , 流式套接字 21 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 22 if (s == INVALID_SOCKET) 23 { 24 cout << "socket error:" << WSAGetLastError() << endl; 25 return 0; 26 } 27 28 //2.绑定socket到一个IP地址和端口 29 sockaddr_in addr;//不建议使用sockaddr,建议用sockaddr_in 30 addr.sin_port = htons(8000);//网络字节序 31 addr.sin_addr.S_un.S_addr =inet_addr( "127.0.0.1" );//网络字节序 32 addr.sin_family = AF_INET; //地址族 33 int len = sizeof(sockaddr_in); 34 if (bind(s, (sockaddr *)&addr, len) == SOCKET_ERROR) 35 { 36 cout << "bind error:" << WSAGetLastError() << endl; 37 return 0; 38 } 39 40 //3.监听, 5代表正在等待完成相应的TCP三路握手过程的队列长度 41 if(listen(s, 5) == SOCKET_ERROR) 42 { 43 cout << "listen error:" << WSAGetLastError() << endl; 44 return 0; 45 } 46 47 48 //4.接受客户端请求,并且返回和客户端通讯的套接字 49 sockaddr_in addrClient;// 保存客户端IP地址端口 50 memset(&addrClient, 0, sizeof(sockaddr_in)); 51 len = sizeof(sockaddr_in); 52 SOCKET c= accept(s, (sockaddr*)&addrClient, &len);//成功返回套接字 53 if (c == INVALID_SOCKET) 54 { 55 cout << "accept error:" << WSAGetLastError() << endl; 56 return 0; 57 } 58 59 60 //5.发送,接受消息 61 int ret = 0; 62 do 63 { 64 //向客户端发送数据,不能用监听套接字s,而应该用accept返回的套接字c 65 ret = send(c, "I am Server!", strlen("I am Server!"), 0);//把flag置0 66 67 //接受客户端的消息 68 char buf[64] = {'\0'}; 69 ret = recv(c, buf, 64, 0);//把flag置0 70 cout << "recv" << inet_ntoa ( addrClient.sin_addr )<<": "<< buf << endl;// inet_ntoa转换为IP字符串 71 } while (ret != SOCKET_ERROR && ret != 0);//对方关闭,返回0 ,错误返回SOCKET_ERROR 72 73 74 //6.关闭套接字 75 closesocket(s); 76 77 78 //清理winsock环境 79 WSACleanup(); 80 81 82 return 0; 83 }