基于TCP的socket编程:
基于UDP的socket编程:
1.基于TCP连接的服务器客户端程序
新建一个win32 console application ,工程名为TCPSrv,再添加一个源程序,取名也为TCPSrv.
服务端程序:
因为要用到win32 套接字的函数,所以要在头文件中包含Winsock2.h这个头文件,并在project -> Setting -> Link -> Object/library modules中添加ws2_32.lib 库文件。编辑TCPSrv.cpp文件:
//TCPSrv.cpp
#include <stdio.h> #include <Winsock2.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库 err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1 HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1 { WSACleanup( );//终止对winsocket的使用 return; } SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); //创建一个服务端的套接字 SOCKADDR_IN addrSrv;//定义一个地址结构体变量 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//对这个地址结构体的成员赋值 //将主机字节序转换成u_long类型的网络字节序 addrSrv.sin_family=AF_INET;//指定地址簇 addrSrv.sin_port=htons(6000);//指定端口号 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//绑定套接字 listen(sockSrv,5);//设置套接字为监听模式,5代表等待连接队列的最大为5 SOCKADDR_IN addrClient;//用来接收客户端的地址信息 int len=sizeof(SOCKADDR);//获得这个结构体的长度 while(1) //保证能够不断接收客户端请求的到来 { SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); //接收套接字的请求 char sendBuf[100];//定义一个Buf字符数组 sprintf(sendBuf,"Welcom %s to http://www.luowei.org", inet_ntoa(addrClient.sin_addr));//将要发送的数据格式化到Buf当中 //inet_ntoa接收一个in_addr类型的参数,返回一个点分十进制表示的IP地址的字符串 send(sockConn,sendBuf,strlen(sendBuf)+1,0);//发送数据 char recvBuf[100];//定义一个用来接收的字符数组 recv(sockConn,recvBuf,100,0);//接收数据 printf("%s\n",recvBuf); closesocket(sockConn);//关闭套接字,释放为这个套接字所分配的资源 } }
客户端程序:
在Workspace 'TCPSrv'上点右键 -> Add New Project To Workspace… , 选择win32 console application ,工程名为TCPClient,目录放到TCPClient下,再添加一个源程序,取名也为TCPClient。编辑:
#include <stdio.h> #include <Winsock2.h> #pragma comment(lib, "Ws2_32.lib") void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库 err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1 HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1 { WSACleanup( );//终止对winsocket的使用 return; } SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);//定义套接屏蔽泵 SOCKADDR_IN addrSrv;//定义一个地址结构体变量 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000); connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//连接 char recvBuf[100]; recv(sockClient,recvBuf,100,0); printf("%s\n",recvBuf); send(sockClient,"This is luowei_Client",strlen("This is luowei_Client")+1,0); //发送消息 closesocket(sockClient); WSACleanup();//终止对套接字库的使用 }
运行,OK !
2.基于TCP连接的服务器客户端程序
新建一个win32 console application ,工程名为UDPSrv,再添加一个源程序,取名也为UDPSrv.
服务端程序:
因为要用到win32 套接字的函数,所以要在头文件中包含Winsock2.h这个头文件,并在project -> Setting -> Link -> Object/library modules中添加ws2_32.lib 库文件。编辑UDPSrv.cpp文件:
#include <stdio.h> #include <Winsock2.h> #pragma comment(lib, "Ws2_32.lib") void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库 err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1 HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1 { WSACleanup( );//终止对winsocket的使用 return; } SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0); //创建一个服务端的套接字 SOCKADDR_IN addrSrv;//定义一个地址结构体变量 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //对这个地址结构体的成员赋值 //htonl将主机字节序转换成u_long类型的网络字节序 addrSrv.sin_family=AF_INET;//指定地址簇 addrSrv.sin_port=htons(6000);//指定端口号 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); SOCKADDR_IN addrClient;//定义一个地址结构变量,用来接收发送方的地址信息 int len=sizeof(SOCKADDR); char recvBuf[100]; recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len); //接收数据 printf("%s\n",recvBuf); closesocket(sockSrv); WSACleanup(); }
客户端程序:
在Workspace 'UDPSrv'上点右键 -> Add New Project To Workspace… , 选择win32 console application ,工程名为UDPClient,目录放到UDPClient下,再添加一个源程序,取名也为UDPClient。编辑:
#include <stdio.h> #include <Winsock2.h> #pragma comment(lib, "Ws2_32.lib") void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库 err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1 HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1 { WSACleanup( );//终止对winsocket的使用 return; } SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0); //创建一个服务端的套接字 SOCKADDR_IN addrSrv;//定义一个地址结构体变量 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); //对这个地址结构体的成员赋值 //hto将主机字节序转换成u_long类型的网络字节序 addrSrv.sin_family=AF_INET;//指定地址簇 addrSrv.sin_port=htons(6000);//指定端口号 sendto(sockClient,"Hello",strlen("Hello")+1,0, (SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); closesocket(sockClient); WSACleanup(); }
3.简单的聊天程序
新建一个win32 console application ,工程名为NetSrv,再添加一个源程序,取名也为NetSrv.
服务端程序:
因为要用到win32 套接字的函数,所以要在头文件中包含Winsock2.h这个头文件,并添加ws2_32.lib 库文件。编辑NetSrv.cpp文件:
#include <stdio.h> #include <Winsock2.h> #pragma comment(lib, "Ws2_32.lib") void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库 err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1 HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1 { WSACleanup( );//终止对winsocket的使用 return; } SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0); //创建一个服务端的套接字 SOCKADDR_IN addrSrv;//定义一个地址结构体变量 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //对这个地址结构体的成员赋值 //htonl将主机字节序转换成u_long类型的网络字节序 addrSrv.sin_family=AF_INET;//指定地址簇 addrSrv.sin_port=htons(6000);//指定端口号 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); char recvBuf[100]; char sendBuf[100]; char tempBuf[200]; SOCKADDR_IN addrClient; int len=sizeof(SOCKADDR); while(1) { recvfrom(sockSrv,recvBuf,100,0, (SOCKADDR*)&addrClient,&len); if('q'==recvBuf[0])//如果接收的字符是q { sendto(sockSrv,"q",strlen("q")+1,0, (SOCKADDR*)&addrClient,len); printf("Chat end!\n"); break;//退出循环 } sprintf(tempBuf,"%s say: %s",inet_ntoa(addrClient.sin_addr),recvBuf); printf("%s\n",tempBuf);//把接收的数据放置tempBuf当中,并打印输出 printf("Please input data:\n"); gets(sendBuf);//读取一行数据 sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len); //把数据发送给客户端 } closesocket(sockSrv); WSACleanup(); }
客户端程序:
在Workspace 'NetSrv'上点右键 -> Add New Project To Workspace… , 选择win32 console application ,工程名为NetClient,目录放到NetClient下,再添加一个源程序,取名也为NetClient。编辑:
#include <stdio.h> #include <Winsock2.h> #pragma comment(lib, "Ws2_32.lib") void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 );//请求一个1.1版本的socket库 err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 1 || //低字节是否为1 HIBYTE( wsaData.wVersion ) != 1 ) //高字节是否也为1 { WSACleanup( );//终止对winsocket的使用 return; } SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0); //创建一个服务端的套接字 SOCKADDR_IN addrSrv;//定义一个地址结构体变量 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); //对这个地址结构体的成员赋值 //htonl将主机字节序转换成u_long类型的网络字节序 addrSrv.sin_family=AF_INET;//指定地址簇 addrSrv.sin_port=htons(6000);//指定端口号 char recvBuf[100]; char sendBuf[100]; char tempBuf[200]; int len=sizeof(SOCKADDR); while(1) { printf("Please input data:\n"); gets(sendBuf); sendto(sockClient,sendBuf,strlen(sendBuf)+1,0, (SOCKADDR*)&addrSrv,len); recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len); if('q'==recvBuf[0]) { sendto(sockClient,"q",strlen("q")+1,0, (SOCKADDR*)&addrSrv,len); printf("Chat end!\n"); break;//退出循环 } sprintf(tempBuf,"%s say :%s",inet_ntoa(addrSrv.sin_addr),recvBuf); printf("%s\n",tempBuf); } closesocket(sockClient); WSACleanup(); }
运行 ! OK !!!