服务端(server)
- #include <stdio.h>
- #include <winsock2.h>
- #pragma comment(lib,"ws2_32.lib") // 把 ws2_32.lib 加到 Link 页的连接库
- #define PORT 15001 // 通信的端口(指服务器端)
- #define ERROR 0
- #define BUFFER_SIZE 1024 // 注意: 此 Server 端数据接收缓冲区>= Client 端数据发送缓冲区 , 否则造成缓冲区溢出
- /*
- 服务端原理:
- 1, 服务器进程创建套接字
- 2, 将本地地址绑定到所创建的套接字上, 以三元组 {<通信协议>,<IP 地址>,<端口号>} 在网络上标识该套接字
- 3, 将套接字置入监听模式, 并准备接受连接请求
- 4, 接受请求之后, 便可接收客户端发来的数据, 并以本地 DOS 命令运行
- */
- int main()
- {
- WSADATA WSAData;
- if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR) // 启动 winsock ,WSAStartup()函数对 Winsock DLL 进行初始化
- {
- printf("Socket initialize fail!\n");
- exit(1);
- }
- SOCKET sock; // 服务进程创建套接字句柄(用于监听)
- if((sock=socket(AF_INET,SOCK_STREAM,0))==ERROR) // 调用 socket()函数创建一个流套接字, 参数(网络地址类型, 套接字类型, 网络协议)
- {
- printf("Socket create!\n");
- WSACleanup();
- exit(1);
- }
- struct sockaddr_in ServerAddr; //sockaddr_in 结构用来标识 TCP/IP 协议下的地址, 可强制转换为 sockaddr 结构
- ServerAddr.sin_family=AF_INET; //sin_family 字段必须设为 AF_INET, 表示该 Socket 处于 Internet 域
- ServerAddr.sin_port=htons(PORT); //sin_port 字段用于指定服务端口, 注意避免冲突
- ServerAddr.sin_addr.s_addr=INADDR_ANY; //sin_addr 字段用于把一个 IP 地址保存为一个 4 字节的数, 无符号长整型, 根据不同用法还可表示本地或远程 IP 地址
- if(bind(sock,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR) // 调用 bind()函数将本地地址绑定到所创建的套接字上, 以在网络上标识该套接字
- {
- printf("Bind fail!\n");
- closesocket(sock);
- WSACleanup();
- exit(1);
- }
- printf("Server Socket Port:%d\n",ntohs(ServerAddr.sin_port));
- if(listen(sock,10)==SOCKET_ERROR) // 调用 listen()函数将套接字置入监听模式并准备接受连接请求, 参数(已捆绑未连接的套接字描述字, 正在等待连接的最大队列长度)
- {
- printf("Listen fail!\n");
- closesocket(sock);
- WSACleanup();
- exit(1);
- }
- SOCKET msgsock; // 创建一个新的套接字(用于接收 accept 函数的返回值, 即表示已经接受的那个客户端的连接, 进而接收 Client 发来的数据)
- char buf[BUFFER_SIZE]; // 数据接收缓冲区
- while(1)
- {
- if((msgsock=accept(sock,(LPSOCKADDR)0,(int *)0))==INVALID_SOCKET) // 进入监听状态后, 调用 accept()函数接收客户端的连接请求, 并把连接传给 msgsock 套接字, 原 sock 套接字继续监听其他客户机连接请求
- {
- printf("Accept fail!\n");
- continue;
- }
- memset(buf,0,sizeof(buf)); // 初始化数据接收缓冲区
- recv(msgsock,buf,BUFFER_SIZE,0); // 接收客户端发送过来的数据
- if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t') //"exit" 命令, 退出程序
- {
- printf("The End.\n");
- break;
- }
- printf("C:\\Socket\\Server>%s",buf);
- system(buf); // 本地运行客户端传来的命令: 这一点太厉害了, 假如传一个 Format 命令, 那服务端可能就毁了
- closesocket(msgsock);
- }
- closesocket(sock); // 关闭套接字
- WSACleanup(); // 终止对 Winsock DLL 的使用, 并释放资源
- return 0;
- }
客户端(client)
- #include <winsock2.h>
- #include <stdio.h>
- #pragma comment(lib,"ws2_32.lib") // 把 ws2_32.lib 加到 Link 页的连接库
- //#define IP "172.18.68.243" // 在两台计算机上测试, IP 为 Server 端的 IP 地址
- #define IP "127.0.0.1" // 在一台计算机上测试, IP 为本地回送地址
- #define PORT 15001 // 注意: 客户端设置通信的端口 = 服务端的端口
- #define BUFFER_SIZE 1024 // 数据发送缓冲区大小
- /*
- 客户端原理:
- 1, 客户端进程创建套接字
- 2, 客户端向服务端进程发出连接请求
- 3, 当服务端接受请求后, 客户端便可向服务端发送数据
- */
- int main()
- {
- char buf[BUFFER_SIZE]; //buf 数组存放客户端发送的消息
- int inputLen; // 用于输入字符自增变量
- while(1)
- {
- printf("C:\\Socket\\Client>");
- inputLen=0;
- memset(buf,0,sizeof(buf));
- while((buf[inputLen++]=getchar())!='\n') // 输入以回车键为结束标识
- {
- ;
- }
- if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t')
- {
- printf("The End.\n");
- break;
- }
- WSADATA WSAData;
- if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR) //WSAStartup()函数对 Winsock DLL 进行初始化
- {
- printf("Socket initialize fail!\n");
- continue;
- }
- SOCKET sock; // 客户端进程创建套接字
- if((sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR) // 创建流套接字(与服务端保持一致)
- {
- printf("Socket create fail!\n");
- WSACleanup();
- continue;
- }
- struct sockaddr_in ClientAddr; //sockaddr_in 结构用来标识 TCP/IP 协议下的地址, 可强制转换为 sockaddr 结构
- ClientAddr.sin_family=AF_INET; // 指 Internet 域
- ClientAddr.sin_port=htons(PORT); // 指定服务端所预留的端口
- ClientAddr.sin_addr.s_addr=inet_addr(IP); // 指定服务端所绑定的 IP 地址
- if(connect(sock,(LPSOCKADDR)&ClientAddr,sizeof(ClientAddr))==SOCKET_ERROR) // 调用 connect()函数, 向服务器进程发出连接请求
- {
- printf("Connect fail!\n");
- closesocket(sock);
- WSACleanup();
- continue;
- }
- send(sock,buf,BUFFER_SIZE,0); // 向服务器发送数据
- closesocket(sock); // 关闭套接字
- WSACleanup(); // 终止对 Winsock DLL 的使用, 并释放资源, 以备下一次使用
- }
- return 0;
- }
参考文献: https://blog.csdn.net/lynch0571
来源: http://www.bubuko.com/infodetail-2637200.html