任務
使用數據報套接字的C/S模型,編寫一個字符界面的簡單聊天程序,輸入"quit"結束聊天。
服務器
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include "iostream"
#include "winsock.h"
#define PORT 65432
#define BUFFER_LEN 1000
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main() {
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2);
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
cout << "winsock.dll failed!" << endl;
return 0;
}
//數據報套接字
SOCKET udpsocket;
udpsocket = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in localaddr;
struct sockaddr_in fromaddr;
int len = sizeof(fromaddr);
//綁定地址
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(PORT);
localaddr.sin_addr.S_un.S_addr = INADDR_ANY;
bind(udpsocket, (struct sockaddr *)&localaddr, sizeof(localaddr));
//循環執行數據收發
char buffer[BUFFER_LEN] = "";
while (true) {
cout << "waiting ......" << endl;
if (recvfrom(udpsocket, buffer, sizeof(buffer), 0, (struct sockaddr *)&fromaddr, &len) == SOCKET_ERROR) {
cout << "receive failed" << endl;
break;
}
else {
cout << "Received from: " << inet_ntoa(fromaddr.sin_addr) << " " << buffer << endl;
if (strcmp(buffer, "bye") == 0)continue;
}
cout << "Input message:";
cin.getline(buffer, sizeof(buffer));
sendto(udpsocket, buffer, strlen(buffer) + 1, 0, (struct sockaddr *)&fromaddr, len);
if (strcmp(buffer, "quit") == 0)break;
}
closesocket(udpsocket);
WSACleanup();
return 0;
}
客戶端
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include "iostream"
#include "winsock.h"
#define PORT 65432
#define BUFFER_LEN 1000
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main() {
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2);
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
cout << "winsock.dll failed!" << endl;
return 0;
}
char serverIP[20];
cout << "請輸入IP地址:" << endl;
cin.getline(serverIP, sizeof(serverIP));
//數據報套接字
SOCKET udpsocket;
udpsocket = socket(AF_INET, SOCK_DGRAM, 0);
//填寫地址
struct sockaddr_in serveraddr;
int len = sizeof(sockaddr_in);
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(PORT);
serveraddr.sin_addr.S_un.S_addr = inet_addr(serverIP);
//循環執行數據收發
char buffer[BUFFER_LEN] = "";
while (true) {
cout << "input message: ";
cin.getline(buffer, sizeof(buffer));
if (sendto(udpsocket, buffer, strlen(buffer) + 1, 0, (struct sockaddr *)&serveraddr, len) == SOCKET_ERROR) {
cout << "send failed" << endl;
break;
}
else {
if (strcmp(buffer, "quit") == 0)break;
if (recvfrom(udpsocket, buffer, sizeof(buffer), 0, NULL, NULL) == SOCKET_ERROR) {
cout << "receive failed" << endl;
break;
}
else {
cout << "received from sever: " << buffer << endl;
if (strcmp(buffer, "quit") == 0)break;
}
}
}
closesocket(udpsocket);
WSACleanup();
return 0;
}