进行消息转发 StartRecv();
Sleep(2000); }
return 0; }
//启动服务器 int StartServer() {
//存放套接字信息的结构 WSADATA wsaData = { 0 };
SOCKADDR_IN ServerAddr = { 0 }; //服务端地址
USHORT uPort = 18000; //服务器监听端口
//初始化套接字
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
printf(\ return -1; }
//判断版本
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
printf(\ return -1; }
//创建套接字
g_ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (g_ServerSocket == INVALID_SOCKET) {
printf(\ return -1; }
//设置服务器地址
ServerAddr.sin_family = AF_INET;//连接方式
ServerAddr.sin_port = htons(uPort);//服务器监听端口
ServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//任何客户端都能连接这个服务器
//绑定服务器
if (SOCKET_ERROR == bind(g_ServerSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr)))
{
printf(\ closesocket(g_ServerSocket); return -1; }
//设置监听客户端连接数
if (SOCKET_ERROR == listen(g_ServerSocket, 20000)) {
printf(\ closesocket(g_ServerSocket); WSACleanup(); return -1; }
_beginthreadex(NULL, 0, ThreadAccept, NULL, 0, 0);
for (int k = 0;k < 100;k++) //让主线程休眠,不让它关闭TCP连接. Sleep(10000000);
//关闭套接字 ClearClient();
closesocket(g_ServerSocket); WSACleanup(); return 0; }
int main() {
StartServer(); //启动服务器
return 0;
} Client code: ?
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include
#pragma comment(lib,\#define RECV_OVER 1 #define RECV_YET 0
char userName[16] = { 0 };
char chatName[16] = { 0 }; int iStatus = RECV_YET; //接受数据
unsigned __stdcall ThreadRecv(void* param) {
char buf[128] = { 0 }; while (1) {
int ret = recv(*(SOCKET*)param, buf, sizeof(buf), 0); if (ret == SOCKET_ERROR) {
Sleep(500); continue; }
if (strlen(buf) != 0) {
printf(\ iStatus = RECV_OVER; } else
Sleep(100); }
return 0; }
//发送数据
unsigned __stdcall ThreadSend(void* param) {
char buf[128] = { 0 }; int ret = 0; while (1) {
int c = getch();
if (c == 27) //ESC ASCII是27 {
memset(buf, 0, sizeof(buf));
printf(\ gets_s(buf);
char b[17] = { 0 }; sprintf(b, \
ret = send(*(SOCKET*)param,b , sizeof(b), 0); if (ret == SOCKET_ERROR)
return 1; continue; }
if(c == 72 || c == 0 || c == 68)//为了显示美观,加一个无回显的读取字符函数
continue; //getch返回值我是经过实验得出如果是返回这几个值,则getch就会自动跳过,具体我也不懂。 printf(\ gets_s(buf);
ret = send(*(SOCKET*)param, buf, sizeof(buf), 0); if (ret == SOCKET_ERROR) return 1; }
return 0; }
//连接服务器
int ConnectServer() {
WSADATA wsaData = { 0 };//存放套接字信息
SOCKET ClientSocket = INVALID_SOCKET;//客户端套接字 SOCKADDR_IN ServerAddr = { 0 };//服务端地址 USHORT uPort = 18000;//服务端端口 //初始化套接字
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
printf(\ return -1; }
//判断套接字版本
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
printf(\ return -1; }
//创建套接字
ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ClientSocket == INVALID_SOCKET) {
printf(\ return -1; }
//输入服务器IP
printf(\ char IP[32] = { 0 }; gets_s(IP);
//设置服务器地址
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(uPort);//服务器端口
ServerAddr.sin_addr.S_un.S_addr = inet_addr(IP);//服务器地址
printf(\
//连接服务器
if (SOCKET_ERROR == connect(ClientSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr))) {
printf(\ closesocket(ClientSocket); WSACleanup(); return -1; }
printf(\ IP, htons(ServerAddr.sin_port)); printf(\ gets_s(userName);
send(ClientSocket, userName, sizeof(userName), 0); printf(\ gets_s(chatName);
send(ClientSocket, chatName, sizeof(chatName), 0); printf(\
_beginthreadex(NULL, 0, ThreadRecv, &ClientSocket, 0, NULL); //启动接收和发送消息线程 _beginthreadex(NULL, 0, ThreadSend, &ClientSocket, 0, NULL); for (int k = 0;k < 1000;k++) Sleep(10000000); closesocket(ClientSocket); WSACleanup(); return 0; }
int main() {
ConnectServer(); //连接服务器 return 0;
}