简单的socket通信

服务端

#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编译会报错,文章未完,待更新

Advertisements