l 实例编译环境为Microsoft Visual Studio 2010
l 该实例编写了一个基于数据包的客户端/服务器交互程序,在程序启动后,服务器端向客户发送“Hello!I am a server.”信息,客户端向服务器端发送“Hello!I am a client.”信息,双方各自接收到对方的信息将其显示出来。
l 实例执行结果:
图1和图2分别是客户端程序和服务器端程序执行结果,它们是在同一台主机上执行的结果。该主机的IP地址设置为“58.154.232.29”。客户端程序共执行3次,每执行一次服务器端程序就显示与其建立连接的客户端IP地址和端口号,并显示发送的给客户端的字节数。(每次执行时,主机都分配了不同的端口号)
图 1 服务器端程序执行结果
图2 客户端程序执行结果
l 具体的Server.c和client.c程序源代码
//****************************Server.c**********************************//
#include <windows.h>
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")//在¨?vs2010中D添?¨?加¨?此??库a函
#include <stdio.h>
#include <string.h>
#define PROTOPORT 5050
#define BUFFER_LENGTH 1024
#define QLEN 6
//int visits = 0;
int main(int argc, char *argv[]){
int port=PROTOPORT; //协-议°¨?端?口¨?
WSADATA wsaData;
SOCKET sSocket;
struct hostent *ptrh;
struct protoent *ptrp;
struct sockaddr_in sad;//本??地??地??址?¤
struct sockaddr_in cad;//客¨?户?ì端?地??址?¤
int iLen; //客¨?户?ì地??址?¤长?è度¨¨
int iRecv; //接¨?收??数?y据Y长?è度¨¨
int iSend; //发¤?é送¨?的??数?y据Y长?è度¨¨
char buf[1024];
char send_buf[]="Hello!I am a server.";//发¤?é送¨?给?客¨?户?ì的??信?息?é
char recv_buf[BUFFER_LENGTH];//接¨?收??数?y据Y的??缓o冲?区?
printf("Server waiting ...\n");
WSAStartup(0x0101, &wsaData);//第?¨?一°?个?
memset(recv_buf,0,sizeof(recv_buf));
memset((char *)&sad,0,sizeof(sad)); //清?除ysocket结¨?构1
if ( ((int)(ptrp = getprotobyname("udp"))) == 0) {
fprintf(stderr, "cannot map \"udp\" to protocol number");
exit(1);
}
/* Create a socket */
sSocket = socket(AF_INET, SOCK_DGRAM, ptrp->p_proto);
if (sSocket < 0) {
fprintf(stderr, "socket creation failed\n");
exit(1);
}
//建?§立??é服¤t务?器??端?地??址?¤
sad.sin_family = AF_INET; //设?¨¨置?
if (argc > 1) {
port = atoi(argv[1]);
} else {
port = PROTOPORT;
}
if (port > 0){
sad.sin_port = htons((u_short)port);//把??一°?个?双?字??节¨?的??主??机¨?字??节¨?顺3序¨°数?y转?a换?为a网??络?字??节¨?顺3
}
else{
fprintf(stderr,"bad port number %s\n",argv[1]);
exit(1);
}
sad.sin_addr.s_addr = htonl(INADDR_ANY);//设?¨¨置?当???地??IP地??址?¤
if (bind(sSocket, (LPSOCKADDR)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"bind failed\n");
exit(1);
}
//初?始??化??接¨?收??缓o冲?区?
iLen = sizeof(cad);
//进?行D数?y据Y接¨?收??和¨?发¤?é送¨?
while (1) {
iRecv=recvfrom(sSocket, recv_buf,BUFFER_LENGTH,0,(struct sockaddr *)&cad,&iLen);
if ( iRecv< 0)
{
fprintf(stderr, "accept failed\n");
exit(1);
}
//输??出?接¨?受?¨?的??信?息?é
printf("recvfrom() :%s\n",recv_buf);
//给?客¨?户?ì发¤?é信?息?é
iSend=sendto(sSocket,send_buf,sizeof(send_buf),0,(struct sockaddr *)&cad,sizeof(cad));
if (iSend<0)
{
fprintf(stderr, "Sendto failed\n");
exit(1);
}else
printf("send() succeeded.\n");
}
closesocket(sSocket);
WSACleanup();
}
//***********************client.c**********************************//
#include <windows.h>
#include <winsock.h>
#pragma comment(lib,"ws2_32.lib")
#include <io.h>
#include <stdio.h>
#include <string.h>
#define PROTOPORT 5050
#define DATA_BUFFER 1024
int main(int argc, char *argv[]){
WSADATA wsaData;
SOCKET sClient;
struct sockaddr_in sad; //服¤t务?器??端?地??址?¤
int port=5050; //协-议°¨?端?口¨?
int iLen; //服¤t务?器??地??址?¤长?è度¨¨
int iSend; //发¤?é送¨?数?y据Y的??长?è度¨¨
int iRecv; //接¨?收??数?y据Y的??长?è度¨¨
char send_buf[]="Hello!ê?I am a client!";//发¤?é送¨?给?客¨?户?ì的??信?息?é
char recv_buf[5000];//接¨?收??数?y据Y的??缓o冲?区?
WSAStartup(0x0101, &wsaData);//第?¨?一°?个?
//初?始??化??接¨?收??缓o冲?区?
memset(recv_buf,0,sizeof(recv_buf));
memset((char *)&sad,0,sizeof(sad));
//建?§立??é服¤t务?器??端?地??址?¤
sad.sin_family = AF_INET; //设?¨¨置?
sad.sin_addr.s_addr = inet_addr(argv[1]);//设?¨¨置?当???地??IP地??址?¤
sad.sin_port = htons((u_short)port);//把??一°?个?双?字??节¨?的??主??机¨?字??节¨?顺3序¨°数?y转?a换?为a网??络?字??节¨?顺3序¨°
/* Create a socket */
sClient = socket(AF_INET, SOCK_DGRAM, 0);
if (sClient < 0) {
fprintf(stderr, "socket creation failed\n");
exit(1);
}
iLen = sizeof(sad);
//给?服¤t务?器??端?发¤?é信?息?é
iSend=sendto(sClient,send_buf,sizeof(send_buf),0,(struct sockaddr *)&sad,iLen);
if (iSend<0)
{
fprintf(stderr, "Sendto failed\n");
exit(1);
}else
printf("send() succeeded.\n\n");
//从?¨?服¤t务?器??接¨?收??信?息?é
iRecv=recvfrom(sClient, recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&sad,&iLen);
if ( iRecv< 0)
{
fprintf(stderr, "accept failed\n");
exit(1);
}
printf("recvfrom():%s\n",recv_buf);
closesocket(sClient);
WSACleanup();
}