使用软件:Visual Studio 2022
步骤:
1,新建一个空项目,项目名称为Server,解决方案名称为Socket;
2,软件右方解决方案资源管理器中->右击"解决方案"Socket"->添加"新建项目"添加空项目,项目名称为Client;
3,右击"Server"->添加“现有项”,"Server"有一个头文件,一个源文件,多选并添加。"Client"同理;
特别注意:
①Server.h,Server.c属于项目"Server";Client.h,Client.c属于项目"Client";
②Server.c和Client.c中第一行对头文件的引用,/Socket为头文件位置,请做出相应更改;
③右击项目Client->项目->属性->C/C++->常规->SDL检查改为否,不做修的话"inet_addr"会出错。
4,按ctrl+F5先运行Server,再右击"Client"->调试->启动新实例;
5,开始运行。(注意:客户端输入"end"结束连接,连接断开后服务器端再次发送消息不成功,会再次进入监听状态)
服务器端头文件Server.h
#ifndef _SOCKETTCP_H_ #define _SOCKETTCP_H_ #include//Windows平台网络库头文件 #pragma comment(lib,"ws2_32.lib") //库文件 #include #include #define PORT 8888 //端口号 >1024 #define err(errMsg) printf("[line:%d]%s failed code %d",__LINE__,errMsg,WSAGetLastError()) //打开网络库 bool init_Socket(); //关闭网络库 bool close_Socket(); //创建服务端 SOCKET CreateServerSocket(); #endif // ! _SOCKETTCP_H_
服务器端源文件Server.c
#include"../Socket/Server.h" #include#include int main() { init_Socket(); SOCKET serfd = CreateServerSocket(); Sign:printf("IP:127.0.0.1n"); printf("Listening port:%d n", PORT); printf("wait Client connect...n"); //客户端请求连接 SOCKET clifd = accept(serfd, NULL, NULL); if (INVALID_SOCKET == clifd) { err("accept"); } //可以与客户端通信 char recvbuf[BUFSIZ] = { 0 }; char sendbuf[BUFSIZ] = { 0 }; printf("Client connected...n"); while (true) { //接收消息 if (0 < recv(clifd, recvbuf, BUFSIZ, 0)) { printf("recv:%sn", recvbuf); memset(recvbuf, 0, sizeof(recvbuf)); } //给客户端发送消息 printf("send>"); gets_s(sendbuf, BUFSIZ); if (SOCKET_ERROR == send(clifd, sendbuf, strlen(sendbuf), 0)) { err("send"); printf("n"); printf("Client disconnectedn"); goto Sign; } if (INVALID_SOCKET == clifd) { err("accept"); return false; } } closesocket(clifd); closesocket(serfd); close_Socket(); system("pause"); return 0; } bool init_Socket() { WSADATA wsadata; if(0 != WSAStartup(MAKEWORd(2, 2), &wsadata)) { printf("WSAStartup failed code %d", WSAGetLastError()); return false; } //WSA Windows异步套接字 //parm1 请求的Socket版本 //parm2 传出参数 return true; } bool close_Socket() { if (0 != WSACleanup()) { printf("WSACleanup failed code %d", WSAGetLastError()); return false; } return true; } SOCKET CreateServerSocket() { //1 创建空的Socket //af 地址协议族 //type 传输协议类型: 流式套接字 数据报套接字 //protocol 使用的具体传输协议 SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd == INVALID_SOCKET) { err("socket"); return INVALID_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; if (SOCKET_ERROR == bind(fd, &addr, sizeof(addr))) { err("bind"); return false; } //监听 listen(fd, 10); return fd; }
客户端头文件Client.h
#ifndef _SOCKETTCP_H_ #define _SOCKETTCP_H_ #include//Windows平台网络库头文件 #pragma comment(lib,"ws2_32.lib") //库文件 #include #include #define PORT 8888 //端口号 >1024 #define err(errMsg) printf("[line:%d]%s failed code %d",__LINE__,errMsg,WSAGetLastError()) //打开网络库 bool init_Socket(); //关闭网络库 bool close_Socket(); //创建客户端 SOCKET CreateClientSocket(const char *ip); #endif // ! _SOCKETTCP_H_
客户端源文件Client.c
#include"../Socket/Client.h" #include#include int main() { init_Socket(); SOCKET fd = CreateClientSocket("127.0.0.1"); printf("Server connected...n"); printf("tip:Enter 'end' to end the connectionn"); //发送消息 char recvbuf[BUFSIZ] = { 0 }; char sendbuf[BUFSIZ] = { 0 }; char endbuf[BUFSIZ] = {"end"}; while (true) { //发送消息 printf("send>"); gets_s(sendbuf, BUFSIZ); //输入'end'断开连接 if (strcmp(sendbuf,endbuf)== 0) { return false; } if (SOCKET_ERROR == send(fd, sendbuf, strlen(sendbuf), 0)) { err("send"); } //接收消息 if (0 < recv(fd, recvbuf, BUFSIZ, 0)) { printf("recv:%sn", recvbuf); memset(recvbuf, 0, sizeof(recvbuf)); } } closesocket(fd); close_Socket(); system("pause"); return 0; } bool init_Socket() { WSADATA wsadata; if (0 != WSAStartup(MAKEWORd(2, 2), &wsadata)) { printf("WSAStartup failed code %d", WSAGetLastError()); return false; } //WSA Windows异步套接字 //parm1 请求的Socket版本 //parm2 传出参数 return true; } bool close_Socket() { if (0 != WSACleanup()) { printf("WSACleanup failed code %d", WSAGetLastError()); return false; } return true; } SOCKET CreateClientSocket(const char *ip) { //1 创建空的Socket //af 地址协议族 //type 传输协议类型: 流式套接字 数据报套接字 //protocol 使用的具体传输协议 SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd == INVALID_SOCKET) { err("socket"); return INVALID_SOCKET; } //2 与服务器建立连接 struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.S_un.S_addr =inet_addr(ip); if (INVALID_SOCKET == connect(fd, (struct sockaddr*)&addr, sizeof(addr))) { err("connect"); return false; } return fd; }



