本次实验利用UDP协议, 语言环境为 C/C++
利用套接字Socket编程,实现Server/CLient 之间简单的通讯。
结果应为类似所示:
下面贴上代码(参考参考...)
Server 部分:
1 /* UDPServer.cpp */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <winsock2.h>
6 #include <string.h>
7 #include "conio.h"
8 #include <time.h>
9
10 #define BUFLEN 2000 // 缓冲区大小
11 #define WSVERS MAKEWORD(2, 2) // 指明版本2.2
12 #pragma comment(lib,"ws2_32.lib") // 加载winsock 2.2 Llibrary
13
14 /*------------------------------------------------------------------------
15 * main - TCP client for DAYTIME service
16 *------------------------------------------------------------------------
17 */
18 void
19 main(int argc, char *argv[])
20 {
21 char *host = "127.0.0.1"; /* server IP Address to connect */
22
23 char *service = "5050"; /* server port to connect */
24 struct sockaddr_in sin; /* an Internet endpoint address */
25 struct sockaddr_in from; /* sender address */
26 int fromsize = sizeof(from);
27 char buf[BUFLEN+1]; /* buffer for one line of text */
28 char buf1[BUFLEN+1];
29 SOCKET sock; /* socket descriptor */
30 int cc; /* recv character count */
31
32 char *pts;
33 time_t now;
34
35 WSADATA wsadata;
36 WSAStartup(WSVERS, &wsadata); /* 加载winsock library,WSVERS为请求版本,wsadata返回系统实际支持的最高版本。 */
37 sock = socket(PF_INET, SOCK_DGRAM,IPPROTO_UDP); // 创建UDP套接字, 参数:因特网协议簇(family),数据报套接字,UDP协议号, 返回:要监听套接字的描述符或INVALID_SOCKET
38 memset(&sin, 0, sizeof(sin));
39 sin.sin_family = AF_INET;
40 sin.sin_addr.s_addr = INADDR_ANY; // 绑定(监听)所有的接口。
41 sin.sin_port = htons((u_short)atoi(service)); // 绑定指定接口。atoi--把ascii转化为int,htons -- 主机序(host)转化为网络序(network), 为short类型。
42 bind(sock, (struct sockaddr *)&sin, sizeof(sin)); // 绑定本地端口号(和本地IP地址)
43
44 (void) time(&now); // 取得系统时间
45 pts = ctime(&now); // 把时间转换为字符串
46 printf(" \t UDP(Server) Echo增强程序\n\n");
47 while(!_kbhit()){ //检测是否有按键
48 flag1: cc = recvfrom(sock, buf, BUFLEN, 0, (SOCKADDR *)&from, &fromsize); //接收客户数据。返回结果:cc为接收的字符数,from中将包含客户IP地址和端口号。
49 sprintf(buf1," \t\t 时间: %s \t\t Client【IP: %s 端口号: %d 】\n \t\t 数据: %s",pts,inet_ntoa(from.sin_addr),from.sin_port,buf);
50 if (cc == SOCKET_ERROR){
51 printf("recvfrom() failed; %d\n", WSAGetLastError());
52 break;
53 }
54 else if (cc == 0)
55 break;
56 else{
57 buf[cc] = '\0';
58 printf("您收到的数据为:\n %s\n", buf1);
59 printf("将自动把此数据返回给 Client \n");
60 goto flag2;
61 }
62
63 }
64
65 flag2: cc = sendto(sock, buf1, 1000, 0,(SOCKADDR *)&from, sizeof(from));
66 if (cc == SOCKET_ERROR){
67 printf("发送失败,错误号:%d\n", WSAGetLastError());
68 }
69 else{
70 printf("发送成功\n");
71 goto flag1;
72 }
73
74 // cc = recvfrom(sock, buf, BUFLEN, 0, (SOCKADDR *)&from, &fromsize);
75
76 closesocket(sock);
77 GlobalFree(buf);
78 WSACleanup(); /* 卸载某版本的DLL */
79 }
Client 部分:
1 /* UDPClient.cpp */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <winsock2.h>
6 #include <string.h>
7 #include <time.h>
8
9 #define BUFLEN 2000 // 缓冲区大小
10 #define WSVERS MAKEWORD(2, 2) // 指明版本2.2
11 #pragma comment(lib,"ws2_32.lib") // 加载winsock 2.2 Llibrary
12
13 void
14 main(int argc, char *argv[])
15 {
16 char *host = "127.0.0.1"; /* server IP to connect */
17
18 char *service = "5050"; /* server port to connect */
19 struct sockaddr_in toAddr; /* an Internet endpoint address */
20 char buf[BUFLEN+1]; /* buffer for one line of text */
21 SOCKET sock; /* socket descriptor */
22 int cc; /* recv character count */
23 char *pts; /* pointer to time string */
24 time_t now; /* current time */
25
26 int toAddrsize = sizeof(toAddr);
27
28 WSADATA wsadata;
29 WSAStartup(WSVERS, &wsadata); /* 启动某版本Socket的DLL */
30
31 sock = socket(PF_INET, SOCK_DGRAM,IPPROTO_UDP);
32
33 memset(&toAddr, 0, sizeof(toAddr));
34 toAddr.sin_family = AF_INET;
35 toAddr.sin_port = htons((u_short)atoi(service)); //atoi:把ascii转化为int. htons:主机序(host)转化为网络序(network), s--short
36 toAddr.sin_addr.s_addr = inet_addr(host); //如果host为域名,需要先用函数gethostbyname把域名转化为IP地址
37
38
39 // memset(buf,' ',1000); //fill 1000 bytes with 'e'
40 buf[1000] = '\0';
41 (void) time(&now); // 取得系统时间
42 pts = ctime(&now); // 把时间转换为字符串
43 // memcpy(buf,pts,strlen(pts));
44 sprintf(buf,"%s ",pts);
45 printf(" UDP(Client) Echo增强程序\n\n");
46 printf(" 时间 :%s",buf);
47
48
49
50 cc = sendto(sock, buf, 1000, 0,(SOCKADDR *)&toAddr, sizeof(toAddr));
51 flag2: if (cc == SOCKET_ERROR){
52 printf("发送失败,错误号:%d\n", WSAGetLastError());
53 }
54 else{
55 printf(" 发送成功 \n");
56 cc = recvfrom(sock, buf, BUFLEN, 0, (SOCKADDR *)&toAddr, & toAddrsize);
57 printf(" 您接收到的数据为:\n %s \n",buf);
58 printf("键入 # 继续发送,键入 @ 停止发送\n");
59 scanf("%s",pts);
60 if(pts[0]=='#')
61 {
62 printf(" 请输入要发送的数据 :\n");
63 goto flag1;
64 }
65 if(pts[0]=='@')
66 goto end;
67
68
69 }
70
71 flag1:
72 scanf("%s",pts);
73 sprintf(buf,"%s ",pts);
74 cc = sendto(sock, buf, 1000, 0,(SOCKADDR *)&toAddr, sizeof(toAddr));
75
76 goto flag2;
77
78
79
80 getchar();
81
82 closesocket(sock);
83
84 end: GlobalFree(buf);
85 WSACleanup(); /* 卸载某版本的DLL */
86
87 getchar();
88
89 }