服务端
#pragma comment(lib, "ws2_32.lib") #include <Winsock2.h> #include <stdio.h> void main() { WORD wVersionRequested; // winsock的版本 WSADATA wsaData; // winsock结构体 int err; // 错误信息 // 配置Windows Socket版本 wVersionRequested = MAKEWORD( 2, 2 ); // 初始化Windows Socket err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { // 启动错误,程序结束 return; } /* * 确认的WinSock DLL支持2.2 * 请注意如果DLL支持的版本大于2.2至2.2 * 它仍然会返回在wVersion2.2的版本 */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { // 启动错误,程序结束 WSACleanup( ); // 终止Winsock 2 DLL (Ws2_32.dll) 的使用 return; } SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); // 定义服务器端socket SOCKADDR_IN addrSrv; // socket本地地址 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); // 本机IP addrSrv.sin_family=AF_INET; // 协议类型是INET addrSrv.sin_port=htons(6000); // 绑定端口是6000 // 将服务器端socket绑定在本地端口 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); // Listen 监听端口 listen(sockSrv,5); // 等待连接数目 printf("Listening...n"); SOCKADDR_IN addrClient; int len=sizeof(SOCKADDR); while(1) { SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len); char sendBuf[100]; sprintf(sendBuf,"welcome %s to me, this is the server clientn", inet_ntoa(addrClient.sin_addr)); // 获取到联接则发送字符串 send(sockConn,sendBuf,strlen(sendBuf)+1,0); char recvBuf[100]; // 获取返回数据 recv(sockConn,recvBuf,100,0); printf("%sn",recvBuf); // 关闭socket closesocket(sockConn); } }
客户端
#pragma comment(lib, "ws2_32.lib") #include <Winsock2.h> #include <stdio.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { // 启动错误,程序结束 WSACleanup( ); 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("%sn",recvBuf); char message[50] = "这里是Lellansin!"; // 发送数据 send(sockClient,message,strlen(message)+1,0); // 关闭socket closesocket(sockClient); WSACleanup(); getchar(); }
socket 常见函数
accept函数
int accept( SOCKET s, struct sockaddr *addr, int *addrlen);
参数一 s
设置监听socket,该套接口在listen()设置。
参数二 addr (可选)
指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
参数三 addrlen (可选)
指针,指向存有addr地址长度的整形数。
返回:
成功:非负描述字
失败:-1
accept默认会阻塞进程,直到有客户端建立连接后返回,它返回的是连接用的socket。如果accept成功返回,则服务器与客户已经正确建立连接了,此时服务器通过accept返回的socket来完成与客户的通信。
send函数
int send( SOCKET s, const char *buf, int len, int flags );
不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。
参数一 s
指定发送端socket描述符;
参数二 *buf
指明存放要发送的数据的缓冲区;
参数三 len
指明实际要发送的数据的字节数;
参数四 flags
一般置零
将*buf指向的字符串发送至客户端
recv函数
int recv( SOCKET s, char *buf, int len, int flags );
不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。
参数一 s
指定接收端socket描述符;
参数二 *buf
指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
参数三 len
指明buf的长度;
参数四 flags
一般置0。
获取到客户端返回的字符串并将其写入到buf中
备注:
以上语法遵从c++,如果用c编译会报错,文章未完,待更新