Clion要在CMakeLists.txt加一条link_libraries(ws2_32)
CodeBlock要link对应的文件
遇到一堆疑难杂症,顺便学习一下多线程
效果图:
![!](https://img-blog.csdnimg.cn/20210101224209783.png)
服务器端编程的步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:绑定套接字到一个 IP 地址和一个端口上(bind());
3:将套接字设置为监听模式等待连接请求(listen());
4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
5:用返回的套接字和客户端进行通信(send()/recv());
6:返回,等待另一连接请求;
7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
服务器端代码如下:
#include <stdio.h>
#include <Winsock2.h>
#include <iostream>
#include <thread>
int main() {
setvbuf(stdout, NULL, _IONBF, 0);
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{ return 0; }
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
WSACleanup();
return 1;
}
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
bind(sockSrv, (SOCKADDR *) &addrSrv, sizeof(SOCKADDR));
listen(sockSrv, 5);
printf("等待客户端连接。。。。。。\n");
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
//void run(SOCKET);
void run1(SOCKET);
SOCKET sockConn = accept(sockSrv, (SOCKADDR *) &addrClient, &len);
printf("连接成功\n");
//std::thread t(run,sockConn);
std::thread t1(run1,sockConn);
t1.detach();
printf("请输入你想说的话:\n");
while (1) {
//SOCKET sockConn = accept(sockSrv, (SOCKADDR *) &addrClient, &len);
char a[50];
//std::cin.getline(a, 50);
std::cin>>a;
send(sockConn, a, strlen(a) + 1, 0);
/*char recvBuf[50];
recv(sockConn, recvBuf, 50, 0);
printf("我收到了:%s\n", recvBuf);
closesocket(sockConn);*/
}
closesocket(sockConn);
}
void run(SOCKET sockClient){
while(1) {
printf("请输入你想说的话:\n");
char a[50];
std::cin.getline(a, 50);
send(sockClient, a, strlen(a) + 1, 0);
}
}
void run1(SOCKET sockClient) {
while (1) {
char recvBuf[50];
recv(sockClient, recvBuf, 50, 0);
//if (recv(sockClient, recvBuf, 50, 0)==-1) { std::cout << "断开连接!\n";break; }
if (recvBuf!=NULL)
printf("我收到了:%s\n", recvBuf);
//memset(recvBuf,NULL,sizeof(recvBuf));
}
}
客户端编程的步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:向服务器发出连接请求(connect());
3:和服务器端进行通信(send()/recv());
4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
客户端的代码如下:
#include <stdio.h>
#include <Winsock2.h>
#include <iostream>
#include <thread>
using namespace std;
int main() {
setvbuf(stdout, NULL, _IONBF, 0);
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) { return 0; }
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
WSACleanup();
return 1;
}
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
connect(sockClient, (SOCKADDR *) &addrSrv, sizeof(SOCKADDR));
void run(SOCKET);
void run1(SOCKET);
std::thread t(run1,sockClient);
//std::thread t1(run,sockClient);
t.detach();
// t1.join();
printf("请输入你想说的话:\n");
while(true) {
char a[50];
//scanf("%s",a);
cin.getline(a, 50);
send(sockClient, a, strlen(a) + 1, 0);
/*char recvBuf[50];
recv(sockClient, recvBuf, 50, 0);
printf("我收到了:%s\n", recvBuf);*/
}
closesocket(sockClient);
WSACleanup();
}void run(SOCKET sockClient){
while(1) {
printf("请输入你想说的话:\n");
char a[50];
//scanf("请输入你想说的话:%s",a);
cin>>a;
// cin.getline(a, 50);
send(sockClient, a, strlen(a) + 1, 0);
}
}
void run1(SOCKET sockClient) {
while (1) {
char recvBuf[50];
int res=recv(sockClient, recvBuf, 50, 0);
if (res>0)
printf("我收到了:%s\n", recvBuf);
}
}