下面是代码:
/* TCPClient.cpp -- 用于传递struct */
#include <stdlib.h>
#include <stdio.h>
#include <winsock2.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <process.h>
#include <math.h>
#define BUFLEN 2000 // 缓冲区大小
#define WSVERS MAKEWORD(2, 0) // 指明版本2.0
#pragma comment(lib,"ws2_32.lib") // 指明winsock 2.0 Llibrary
/*------------------------------------------------------------------------
* main - TCP client for DAYTIME service
*------------------------------------------------------------------------*/
SOCKET sock, sockets[100] = { NULL }; /* socket descriptor */ // int cc; /* recv character count */
char *packet = NULL; /* buffer for one line of text */
char *pts, *input;
HANDLE hThread;
unsigned threadID;
unsigned int __stdcall Chat(PVOID PM) {
time_t now;
(void)time(&now);
pts = ctime(&now);
char buf[2000];
while (1) {
int cc = recv(sock, buf, BUFLEN, 0); //cc为接收的字符数
if (cc == SOCKET_ERROR || cc == 0) {
printf("Error: %d ", GetLastError());
printf("与服务器断开连接!\n");
(void)closesocket(sock);
break;
}
else if (cc > 0) {
buf[cc] = '\0';
printf("%s\n", buf);
}
}
return 0;
}
int main(int argc, char *argv[]) {
time_t now;
(void)time(&now);
pts = ctime(&now);
//char *host = "192.168.220.1"; /* server IP to connect */
//char *host = "192.168.220.1";
char *host = "202.116.76.22";
char *service = "5050"; /* server port to connect */
struct sockaddr_in sin; /* an Internet endpoint address */
WSADATA wsadata;
WSAStartup(WSVERS, &wsadata); /* 启动某版本Socket的DLL */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons((u_short)atoi(service)); //atoi:把ascii转化为int. htons:主机序(host)转化为网络序(network), s--short
sin.sin_addr.s_addr = inet_addr(host); //如果host为域名,需要先用函数gethostbyname把域名转化为IP地址
sock = socket(PF_INET, SOCK_STREAM, 0);
hThread = (HANDLE)_beginthreadex(NULL, 0, Chat, NULL, 0, &threadID);
printf(" LET'S CHAT(CLIENT)\n");
connect(sock, (struct sockaddr *)&sin, sizeof(sin));
while (1) {
printf("请输入您要发送的信息:\n");
char buf1[2000];
gets_s(buf1);
if (!strcmp(buf1, "exit"))
goto end;
(void)send(sock, buf1, sizeof(buf1), 0);
(void)time(&now);
pts = ctime(&now);
printf("发送成功!\n当前时间:%s\n", pts);
}
end:
CloseHandle(hThread);
closesocket(sock);
WSACleanup(); /* 卸载某版本的DLL */
printf("按回车键继续...");
getchar();
return 0; /* exit */
}
下面是服务器代码:
/* TCPServer.cpp - main */
#include <stdlib.h>
#include <stdio.h>
#include <winsock2.h>
#include <time.h>
#include "conio.h"
#include<windows.h>
#include<process.h>
#include<math.h>
#define QLEN 5
#define WSVERS MAKEWORD(2, 0)
#define BUFLEN 2000
#pragma comment(lib,"ws2_32.lib") //使用winsock 2.2 library
/*------------------------------------------------------------------------
* main - Iterative TCP server for TIME service
*------------------------------------------------------------------------
*/
SOCKET msock, ssock;
SOCKET sockets[100] = { NULL };
int cc;
char *pts;
time_t now;
char buf[2000]; //buffer
char *input;
HANDLE hThread1, hThread[100] = { NULL };
unsigned int threadID, ThreadID[100], number;
struct sockaddr_in fsin;
struct sockaddr_in Sin;
unsigned int __stdcall Chat(PVOID PM) {
char buf1[2000] = { NULL };
char buf2[2000] = { NULL };
char buf3[2000] = { NULL };
char buf4[2000] = { NULL };
/*char buf1[2000];
char buf2[2000];
char buf3[2000];
char buf4[2000]; */
(void)time(&now);
pts = ctime(&now);
sockets[number] = ssock;
SOCKET sock = ssock;
ThreadID[number] = threadID;
unsigned int threadid = threadID;
sprintf(buf1, "线程号:[%d] 当前时间:%s", threadid, pts);
(void)send(sock, buf1, sizeof(buf1), 0);
sprintf(buf2, "线程号:[%d] 客户IP:[%d] 端口:[%d] enter!\n", threadid, inet_ntoa(Sin.sin_addr), fsin.sin_port);
printf("%s", buf2);
printf("数据已传送到所有用户!\n");
for (int i = 0; i <= number; i++) {
if (sockets[i] != NULL&& sockets[i] != sock) {
(void)send(sockets[i], buf2, sizeof(buf2), 0);
printf("发送至线程号[%d]成功! \n", ThreadID[i]);
}
}
printf("\n");
flag1:
cc = recv(sock, buf3, BUFLEN, 0);
if (cc == SOCKET_ERROR || cc == 0) {
(void)time(&now);
pts = ctime(&now);
sprintf(buf3, "线程号:[%d] 客户IP:[%d] 端口:[%d] leave !\n当前时间:%s", threadid, inet_ntoa(Sin.sin_addr), fsin.sin_port, pts);
sock = NULL;
sockets[number] = NULL;
printf("%s", buf3);
printf("数据已传送到所有用户!\n");
for (int i = 0; i <= number; i++) {
if (sockets[i] != NULL && sockets[i] != sock) {
(void)send(sockets[i], buf3, sizeof(buf3), 0);
printf("发送至线程号[%d]成功 !\n", ThreadID[i]);
}
}
printf("\n");
}
else if (cc > 0) {
(void)time(&now);
pts = ctime(&now);
sprintf(buf4, "线程号:[%d] IP:[%d] 端口:[%d] \n消息内容:%s;\n当前时间:%s", threadid, inet_ntoa(Sin.sin_addr), fsin.sin_port, buf3, pts);
printf("%s", buf4);
printf("数据已传送到所有用户!\n");
for (int i = 0; i <= number; i++) {
if (sockets[i] != NULL&&sockets[i] != sock) {
(void)send(sockets[i], buf4, sizeof(buf4), 0);
printf("发送至线程号[%d]成功!\n", ThreadID[i]);
}
}
printf("\n");
goto flag1;
}
(void)closesocket(sock);
return 0;
}
void main(int argc, char *argv[]) {
int alen; /* from-address length*/
WSADATA wsadata;
char *service = "5050";
WSAStartup(WSVERS, &wsadata); //加载 winsock 2.2 library
msock = socket(PF_INET, SOCK_STREAM, 0); //生成套接字。TCP协议号=6, UDP协议号=17
memset(&Sin, 0, sizeof(Sin));
Sin.sin_family = AF_INET;
Sin.sin_addr.s_addr = INADDR_ANY; //指定绑定接口的IP地址。INADDR_ANY表示绑定(监听)所有的接口。
Sin.sin_port = htons((u_short)atoi(service)); //atoi--把ascii转化为int,htons - 主机序(host)转化为网络序(network), s(short)
bind(msock, (struct sockaddr *)&Sin, sizeof(Sin)); // 绑定端口号(和IP地址)
listen(msock, 5); //队列长度为5
printf(" LET'S CHAT (SERVER) \n");
(void)time(&now); pts = ctime(&now);
printf("当前时间:%s", pts);
number = -1;
while (1) { //检测是否有按键
alen = sizeof(struct sockaddr);
ssock = accept(msock, (struct sockaddr *)&fsin, &alen);
number++;
hThread[number] = (HANDLE)_beginthreadex(NULL, 0, Chat, NULL, 0, &threadID);
}
(void)closesocket(msock);
WSACleanup(); //卸载载 winsock 2.2 library
}