C++网络编程之,客户连接服务器,并向服务器发信息,服务器接收信息,当输入End两者全关闭。
如果两者需要相互收和发信息,需要掌握多线程。
- //tcpSocket.h
-
- #pragma once
- #ifndef _TCPSOCKET_H_
- #define _TCPSOCKET_H_
- #define _CRT_NONSTDC_NO_WARNINGS
- #define _WINSOCK_DEPRECATED_NO_WARNINGS
- #include
- #include
- //网络编程,要引用这两个
- #include
- #pragma comment(lib, "ws2_32.lib")
- //后续的连接端口,0~65535,但是在定义时建议使用10000以上的端口,因为存在端口保留和占用的情况
- #define PORT 65533
- //定义一个err函数,方便后续debug时根据最后的错误获取信息
- #define err(errMsg) printf("[line: %d]%s failed code %d\n", __LINE__, errMsg, WSAGetLastError())//该函数用来获取WSA最后发生错误的代码
-
- using namespace std;
-
-
- //打开网络库
- bool init_Socket();
- //关闭网络库
- bool close_Socket();
- //创建服务端socket
- SOCKET CreatServerScoket();
- //创建客户端socket
- SOCKET CreatClientScoket(const char* ip);
-
-
- #endif // !_TCPSOCKET_H
-
-
- //tcpSocket.cpp
-
- #include "tcpSocket.h"
-
- bool init_Socket()
- {
- WSADATA data;
- if (WSAStartup(MAKEWORD(2, 2), &data) != 0)
- //Windows socket async :Windows异步套接字,使用前必须要对其进行初始化
- {
- err("WSAStartup");
- return false;
- }
- return true;
- }
-
- bool close_Socket()
- {
- if (WSACleanup() != 0)
- //使用完了要关闭网络库
- {
- err("WSACleanup");
- return false;
- }
- return true;
- }
-
- SOCKET CreatServerScoket()
- {
- //1、创建空的socket
- /*
- parm1:AF 地址协议族 IPv4, IPv6
- parm2:type 地址协议类型 流式套接字, 数据报
- parm3:protocol 使用具体的某个传输协议
- */
- SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (fd == INVALID_SOCKET)
- {
- err("SOCKET");
- }
- //2、绑定ip地址和端口号
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;//和创建时要一样
- addr.sin_port = htons(PORT); //把主机字节顺序转换为网络字节顺序
- addr.sin_addr.S_un.S_addr = ADDR_ANY;//inet_addr("127.0.0.1")
-
- if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
- {
- err("bind");
- return false;
- }
- //3、监听电话:
- listen(fd, 10);
- return fd;
- }
-
- SOCKET CreatClientScoket(const char* ip)
- {
- //1、创建空的socket
- /*
- parm1:AF 地址协议族 IPv4, IPv6
- parm2:type 地址协议类型 流式套接字, 数据报
- parm3:protocol 使用具体的某个传输协议
- */
- SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (fd == INVALID_SOCKET)
- {
- err("SOCKET");
- }
- //2、绑定ip地址和端口号
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;//和创建时要一样
- addr.sin_port = htons(PORT); //把主机字节顺序转换为网络字节顺序
- addr.sin_addr.S_un.S_addr = inet_addr(ip);
- //3、与服务器建立连接
- if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == INVALID_SOCKET)
- {
- err("connect");
- return false;
- }
- return fd;
- }
- //Server.cpp
-
-
- #include"tcpSocket.h"
- int main()
- {
- init_Socket();//初始化网络库
- SOCKET serfd = CreatServerScoket();//创建服务端socket
- cout << "wait client connect...\n";
- SOCKET clifd = accept(serfd, NULL, NULL); //如果有客户端请求连接
- if (clifd == INVALID_SOCKET)//失败就输出如下错误
- {
- err("accept");
- }
-
- char buf[BUFSIZ * 2] = { 0 };//定义接收缓冲区并初始化
- while (1)
- {
- if (recv(clifd, buf, BUFSIZ, 0) > 0)//接受并输出
- {
- if (strcmp(buf, "End") == 0)
- break;
- cout << buf << endl;
- memset(buf, 0, sizeof(buf));//缓冲区初始化,防止后续重复输出
- }
-
-
- }
-
- close_Socket();
- return 0;
- }
-
-
-
- //Client.cpp
-
- #include"tcpSocket.h"
- int main()
- {
- init_Socket();//创建客户端socket
- //SOCKET fd = CreatClientScoket("127.0.0.1");//连接
- SOCKET fd = CreatClientScoket("192.168.0.10");//连接
- char str[] = "connect success";//连接成功
-
- send(fd, str, strlen(str), 0);
- while (1)
- {
- char buf[1024];
- std::cin.getline(buf,1024);
- send(fd, buf, strlen(buf), 0);
- if (strcmp(buf, "End") == 0)
- break;
- }
- closesocket(fd);//关闭客户端socket
- close_Socket();//WSACleanup
- }