本次实验利用TCP/IP, 语言环境为 C/C++
利用套接字Socket编程,实现Server/CLient 之间简单的通讯。
结果应为类似所示:
下面贴上代码(参考参考...)
Server 部分:
1 /* TCPServer.cpp - main */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <winsock2.h>
6 #include <time.h>
7 #include "conio.h"
8
9 #define QLEN 5
10 #define WSVERS MAKEWORD(2, 0)
11 #define BUFLEN 20000
12 #pragma comment(lib,"ws2_32.lib") //使用winsock 2.2 library
13 /*------------------------------------------------------------------------
14 * main - Iterative TCP server for TIME service
15 *------------------------------------------------------------------------
16 */
17 char buf[20000];
18 char buf1[20000];
19 char buf2[20000];
20 void main(int argc, char *argv[])
21 /* argc: 命令行参数个数, 例如:C:\> TCPServer 8080
22 argc=2 argv[0]="TCPServer",argv[1]="8080" */
23 {
24 struct sockaddr_in fsin; /* the from address of a client */
25 SOCKET msock, ssock; /* master & slave sockets */
26 WSADATA wsadata;
27 char *service = "5050";
28 struct sockaddr_in sin; /* an Internet endpoint address */
29 int alen; /* from-address length */
30 char *pts; /* pointer to time string */
31 // char pts[2000];
32 time_t now; /* current time */
33 int cc;
34
35 WSAStartup(WSVERS, &wsadata); // 加载winsock library。WSVERS指明请求使用的版本。wsadata返回系统实际支持的最高版本
36 msock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // 创建套接字,参数:因特网协议簇(family),流套接字,TCP协议
37 // 返回:要监听套接字的描述符或INVALID_SOCKET
38
39 memset(&sin, 0, sizeof(sin)); // 从&sin开始的长度为sizeof(sin)的内存清0
40 sin.sin_family = AF_INET; // 因特网地址簇(INET-Internet)
41 sin.sin_addr.s_addr = INADDR_ANY; // 监听所有(接口的)IP地址。
42 sin.sin_port = htons((u_short)atoi(service)); // 监听的端口号。atoi--把ascii转化为int,htons--主机序到网络序(16位)
43 bind(msock, (struct sockaddr *)&sin, sizeof(sin)); // 绑定监听的IP地址和端口号
44
45 listen(msock, 5); // 等待建立连接的队列长度为5
46
47 while(!_kbhit()){ // 检测是否有按键
48 alen = sizeof(struct sockaddr); // 取到地址结构的长度
49 ssock = accept(msock, (struct sockaddr *)&fsin, &alen); // 如果有新的连接请求,返回连接套接字,否则,被阻塞。fsin包含客户端IP地址和端口号
50
51 (void) time(&now); // 取得系统时间
52 pts = ctime(&now); // 把时间转换为字符串
53 sprintf(buf,"IP :%s 端口号: %d\n",inet_ntoa(fsin.sin_addr),fsin.sin_port);
54 // sprintf(buf,"%d:%d Hello my friends ! %s",inet_ntoa(sin.sin_addr),fsin.sin_port,pts);
55 (void) send(ssock, buf, strlen(pts), 0); // 把缓冲区(指针,长度)的数据发送出去
56 printf(" TCP(Server) Echo增强程序 \n\n");
57 printf(" 时间: %s\n", pts);
58 printf(" %s\n", buf); // 显示发送字符串
59 printf("请等待接收数据 :\n");
60
61 //flag1:
62 // printf("\n您还要传送什么?\n");
63 // printf(" 如果想临时改为接收,请键入 * \n");
64 // scanf("%s",pts);
65
66 // if(pts[0] == '*')
67 // {
68 // printf("\n请等待接收数据\n");
69 // sprintf(buf1,"%s",pts);
70 // (void) send(ssock, buf1, strlen(pts), 0);
71 // goto flag2;
72 // }
73 // sprintf(buf1,"%s",pts);
74 // (void) send(ssock, buf1, strlen(pts), 0);
75 // goto flag1;
76 // ssock = accept(msock, (struct sockaddr *)&fsin, &alen);
77
78 flag2: cc = recv(ssock, buf1, BUFLEN, 0);
79 if(cc == SOCKET_ERROR || cc==0)
80 printf("Error: %d.\n",GetLastError()); //出错。其后必须关闭套接字sock。
81 else if(cc > 0) {
82 buf1[cc] = '\0'; // ensure null-termination
83 buf2[cc] = '\0';
84 // if(buf1[0] == '#')
85 // {
86 // printf("\n您接收到的数据为: # , 请传输数据 \n");
87 // goto flag2;
88 // }
89 (void) time(&now);
90 pts = ctime(&now);
91 sprintf(buf2,"%s \n %s",pts,buf1);
92 // strcat(buf2,buf1);
93 printf("\n您接收到的数据为:");
94 // printf(" 时间: %s\n", pts);
95 printf("%s\n", buf2);
96 printf("\n 将自动把此数据返回给客户!\n");
97 (void) send(ssock, buf1, strlen(pts), 0);
98 goto flag2;
99 }
100 (void) closesocket(ssock); // 关闭连接套接字
101 }
102 (void) closesocket(msock); // 关闭监听套接字
103 WSACleanup(); // 卸载winsock library
104
105 }
Client 部分:
1 /* TCPClient.cpp */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <winsock2.h>
6 #include <string.h>
7 #include <time.h>
8 #include "conio.h"
9 #define BUFLEN 20000 // 缓冲区大小
10 #define WSVERS MAKEWORD(2, 0) // 指明版本2.0
11 #pragma comment(lib,"ws2_32.lib") // 使用winsock 2.0 Llibrary
12
13 /*------------------------------------------------------------------------
14 * main - TCP client for TIME service
15 *------------------------------------------------------------------------
16 */
17 char buf1[BUFLEN+1];
18 char buf[BUFLEN+1]; /* buffer for one line of text */
19 void main(int argc, char *argv[])
20 {
21 char *host = "127.0.0.1";
22 // char *host = "10.4.4.146"; /* server IP to connect */
23
24 char *service = "5050"; /* server port to connect */
25 struct sockaddr_in sin,fsin; /* an Internet endpoint address */
26
27
28 SOCKET sock,ssock; /* socket descriptor */
29 int cc,alen; /* recv character count */
30 char *pts ;
31 time_t now;
32 WSADATA wsadata;
33 WSAStartup(WSVERS, &wsadata); //加载winsock library。WSVERS为请求的版本,wsadata返回系统实际支持的最高版本
34
35 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); //创建套接字,参数:因特网协议簇(family),流套接字,TCP协议
36
37 //返回:要监听套接字的描述符或INVALID_SOCKET
38
39 memset(&sin, 0, sizeof(sin)); // 从&sin开始的长度为sizeof(sin)的内存清0
40 sin.sin_family = AF_INET; // 因特网地址簇
41 sin.sin_addr.s_addr = inet_addr(host); // 服务器IP地址(32位)
42 sin.sin_port = htons((u_short)atoi(service)); // 服务器端口号
43 connect(sock, (struct sockaddr *)&sin, sizeof(sin)); // 连接到服务器
44 // alen = sizeof(struct sockaddr);
45 // ssock = accept(sock, (struct sockaddr *)&fsin, &alen);
46 printf(" TCP(Client) Echo增强程序 \n\n");
47 flag1: cc = recv(sock, buf1, BUFLEN+1, 0); // cc为接收到的字符的个数(>0)或对方已关闭(=0)或连接出错(<0)
48 if(cc == SOCKET_ERROR || cc==0)
49 printf("Error: %d.\n",GetLastError()); //出错。其后必须关闭套接字sock。
50 else if(cc > 0) {
51 buf1[cc] = '\0'; // ensure null-termination
52 // if(buf[0] == '*')
53 // {
54 // printf("\n您接收到的数据为: * , 请传输数据 \n");
55 // goto flag2;
56 // }
57 (void) time(&now); // 取得系统时间
58 pts = ctime(&now);
59 printf("您接收到的数据为:\n");
60 printf(" 时间: %s\n",pts);
61 printf(" %s\n",buf1); // 显示所接收的字符串
62 }
63 goto flag2;
64
65 flag2:
66
67
68
69 printf("\n您想传送什么?\n");
70 printf(" 如果想关闭连接,请输入 @ \n");
71 // printf("\n 如果想临时改为接收,请键入 # \n");
72 scanf("%s",pts);
73 if(pts[0] == '@')
74 goto end;
75 // if(pts[0] == '#')
76 // {
77 // printf("\n请等待接收数据\n");
78 // sprintf(buf1,"%s",pts);
79 // (void) send(sock, buf1, strlen(pts), 0);
80 // goto flag1;
81 // }
82 sprintf(buf1,"%s",pts);
83 (void) send(sock, buf1, strlen(pts), 0);
84 goto flag1;
85 end: closesocket(sock); // 关闭监听套接字
86
87 WSACleanup(); // 卸载winsock library
88
89 printf("\n按回车键继续...");
90 getchar(); // 等待任意按键
91 }