1、socket接口概念:
socket接口是TCP/IP网络的API。也就是说,socket接口规定了许多函数和例程,程序员可以用它们来开发TCP/IP网络上的应用程序。
Windows Sockets (winsock)是一套支持多种协议的Windows下的网络编程接口,已成为Windows网络编程的事实上的标准。
Socket实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。
2、Winsock接口编程
(1)包含一个新的头文件
在windows环境下,编写网络程序时需要头文件windows.h
(2)Winsock的初始化和清除
在调用任何其他Winsock函数前,必须先调用WSAStartup函数。其函数原型为:result=WSAStartup(winsock_version,&wsadata);其中Winsock version指明Winsock的版本,wsadata是一个WSADATA变量,WSADATA定义了一个包含Winsock执行体的版本信息、描述和socket信息的数据结构。WSACleanup()函数对应WSAStartup函数,来通知Winsock Stack释放Socket所占用的资源。
(3)建立Socket
socket_handler = socket(int family,int type,int protocol)
其中,family可以选AF_UNIX(Unix socket)、AF_INET(internet);
type:Socket 的类型 (SOCK_STREAM、SOCK_DGRAM),表示字节流或数据报;
protocol:通讯协定(如果使用者不指定则设为0);
如果要建立的是遵从TCP/IP协议的socket,第二个参数type应为SOCK_STREAM,如为 UDP(数据报)的socket,应为SOCK_DGRAM。
(4)配置socket
对于面向连接的客户程序,可以调用connect函数在socket数据结构中保存本地和远地信息,并与远地主机建立连接。
对于无连接的服务器程序以及连接的客户程序,可以调用bind函数将socket与某一本地协议端口绑定。这样就可以对该协议端口进行监听,并通过该端口进行传送与接受。
对于面向连接的服务器程序,首先需用bind函数将socket与一本地协议端口绑定,然后调用listen和accept函数将此socket置于被动的侦听模式并接受和建立连接。
(5)使用socket
Winsock有四个函数用于数据传输:send和sento函数用于数据传送, recv和recvfrom函数用于数据接收。Send和recv函数只用于连接的socket,而sendto和recvfrom不受限制。
1)使用一个连接的socket
下面的程序语句是一个典型的send函数调用
resault= send(socket_handle,message_buffer,buffer_length,flags);
连接的socket数据结构中保存了远地主机的地址信息,send函数将message_buffer里的数据发送往该主机地址。
recv函数从本地协议端口获得数据,并将数据保存到报文缓冲区中:
resault= recv(socket_handle,message_buffer,buffer_length,flags);
2)使用一个无连接的socket
无连接的socket使用sendto和recvfrom函数进行数据传输。
resault= sendto(socket_handle,message_buffer,buffer_length,
flags,socket_address_structure,address_structure_length);
resault= recvfrom(socket_handle,message_buffer,buffer_length,
flags,socket_address_structure,address_structure_length);
client.c
#include <stdio.h> // `这里写代码片`Needed for printf()
#include <string.h> // Needed for memcpy() and strcpy()
#include <windows.h> // Needed for all Winsock stuff
//----- Defines --------------
#define PORT_NUM 1050 // 服务器端口号
#define IP_ADDR "127.0.0.1" // 服务器IP 地址(本机)
//===== Main program ======
int main()
{
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
unsigned int server_s; // Server socket descriptor
struct sockaddr_in server_addr; // Server Internet address
char out_buf[100]; // 100-byte 输出缓冲区
char in_buf[100]; // 100-byte 接收缓冲区
// 初始化 winsock
WSAStartup(wVersionRequested, &wsaData);
// 建立socket
server_s =socket(AF_INET, SOCK_STREAM, 0);
// 配置socket,建立连接
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(PORT_NUM); //端口号
server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP 地址
connect(server_s, (struct sockaddr *)&server_addr, sizeof(server_addr));
// 接收服务器的消息、
recv(server_s, in_buf, sizeof(in_buf), 0);
printf("Received from server... data = '%s' \n", in_buf);
// 向服务器发送消息
strcpy(out_buf, "Message -- client to server");
send(server_s, out_buf, (strlen(out_buf) + 1), 0);
// 关闭sockets
closesocket(server_s);
// 释放 winsock
WSACleanup();
return 0;
}
server.c
#include <stdio.h> // Needed for printf()
#include <string.h> // Needed for memcpy() and strcpy()
#include <windows.h> // Needed for all Winsock stuff
//-----------------------------------------------------
#define PORT_NUM 1050 // 服务器端口号
#define MAX_LISTEN 3 // 最大监听数
//主程序
int main()
{ WORD wVersionRequested = MAKEWORD(1,1); // Stuff for WSA functions
WSADATA wsaData; // Stuff for WSA functions
unsigned int server_s; // Server socket 标示符
struct sockaddr_in server_addr; // Server 地址
unsigned int client_s; // Client socket标示符
struct sockaddr_in client_addr; // Client Internet address
struct in_addr client_ip_addr; // Client IP address
int addr_len; // Internet address length
char out_buf[100]; // 100-byte 输出缓冲区
char in_buf[100]; // 100-byte 接收缓冲区
// 初始化 winsock
WSAStartup(wVersionRequested, &wsaData);
// 建立socket
server_s = socket(AF_INET,SOCK_STREAM, 0);
// 配置socket
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(PORT_NUM); // 使用端口号
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //监听任一IP地址
bind(server_s,(struct sockaddr *)&server_addr, sizeof(server_addr));
// 监听连接
listen(server_s, MAX_LISTEN);
// 接受连接
addr_len = sizeof(client_addr);
client_s = accept (server_s, (struct sockaddr *)&client_addr, &addr_len);
memcpy(&client_ip_addr, &client_addr.sin_addr.s_addr, 4);
// 输出一条接收完成的消息
printf("Accept completed!!! IP address of client = %s port = %d \n", inet_ntoa(client_ip_addr), ntohs(client_addr.sin_port));
// 向客户端发送一条消息
strcpy(out_buf, "Message -- server to client");
send(client_s, out_buf, (strlen(out_buf) + 1), 0);
// 接收从客户端返回的消息
recv(client_s, in_buf, sizeof(in_buf), 0);
printf("Received from client... data = '%s' \n", in_buf);
// 关闭 sockets
closesocket(server_s);
closesocket(client_s);
// 释放winsock
WSACleanup();
return 0;
}
***ps***:(5)如果程序编译连接时出现问题,请按下列步骤操作:
工程----设置-----连接-----工程选项,添加wsock32.lib。
“`