socket编程(1)简单的TCPUDP编程

    技术2026-08-09  5

    socket编程是一种与底层网络协议无关的编程方式,socket意味一种插口,即一个地址配上一个端口就构成了一端插口,既然他与底层协议无关,所以我们在使用socket 编程的时候,就可以任意选用哪种网络协议,如最流行的tcp/ip协议。

    在所有socket编程前腰包含头文件<WinSock2.h>

    下面是基于连接的tcp编程方法:

    服务器端:服务器端是指在tcp中进行监听,也就是被动连接的那一端,服务器端在于客户端建立好连接后,可以同服务器端发送和接收信息,他用一个监听socket进行监听客户端连接,然后得到连接后可以创建一个通信socket进行通信,可以同时与多个客户端通信,服务器端的编程主要有以下几步:

    1.初始winsocket

    WSAStartup(MAKEWORD(2,2),&wsad);

    2.建立一个用于监听的socket     listenSocket=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);

    3.设定监听socket的地址端口,并绑定给这个socket

        listenAddr.sin_family=AF_INET;     listenAddr.sin_addr.s_addr=inet_addr("127.0.0.1");     listenAddr.sin_port=htons(11111);

        if(bind(listenSocket,(SOCKADDR *)(&listenAddr),sizeof(listenAddr))==SOCKET_ERROR){         abort();         return;     }

    4.进行监听  

    if(listen(listenSocket,1)==SOCKET_ERROR){         abort();     }

    5.循环等待新连接进入的socket,如果等到则创建一个socket与之通信,accept操作是一个阻塞的操作。

        while(!stopped){         acceptSocket=WSAAccept(listenSocket,(SOCKADDR*)(&clientAddr),&clientAddrSize,0,0);         if(acceptSocket==INVALID_SOCKET){             int code=WSAGetLastError();             break;         }

    //这里可以得到接入的socket的地址端口         char* add=inet_ntoa(clientAddr.sin_addr);         int port=ntohs(clientAddr.sin_port); //   acceptSocket就是一个已经于客户端连接上的可以进行通信的socket,这里 要 启用一个 新线程用acceptSocket阈值通信

    }

    }

    6、在启用的新线程中一般是这样的:

    调用recv或send函数接收和发送信息

       ret=recv(acceptSocket,buf,1000,0);

    在线程结束前要关闭这个socket   closesocket(acceptSocket);

    7关闭服务器

    首先关闭监听的socket

    closesocket(listenSocket);

    然后清理winsocket WSACleanup();

    **************************************************************************************

    客户端:客户端socket是进行主动连接的那一方,客户端的编程通常是这样的:

    1.初始winsocket

    WSAStartup(MAKEWORD(2,2),&wsad);

    2.建立一个用于连接的socket

        csocket=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);

    3.设定监听socket的地址端口,并绑定给这个socket

        caddres.sin_family=AF_INET;     caddres.sin_addr.s_addr=inet_addr("127.0.0.1");     caddres.sin_port=htons(11111);

    4、想某个服务器发送连接     if(WSAConnect(csocket,(SOCKADDR*)(&caddres),sizeof(caddres),0,0,0,0)==SOCKET_ERROR){         abort();         return;     }

    5调用recv或send函数接收和发送信息

    6通信结束后关闭

    closesocket();    WSACleanup();

    ************************************************************************************

    send和recv的一些方法:

    send()函数不保证会把send的内容全部send出去,这样就可能要多次send(),常用的方法是

    int totalbyte=data.size();     DWORD ret;     WSABUF sendBuf;     sendBuf.len=totalbyte;     sendBuf.buf=data;     while(totalbyte>0){         if(WSASend(csocket,&sendBuf,1,&ret,0,0,0)==SOCKET_ERROR){             abort();             return;         }         totalbyte-=ret;         sendBuf.len=totalbyte;         sendBuf.buf+=ret;     }

    *******************************************************************************************

    下面是基于无连接的UDP编程方法

    这使用的是无连接的协议,TCP是有连接的,即要求在连接之前需要服务器端和客户端都绑定端口,然后连接后可以双向发送接收。

    但是无连接的协议只需要服务器端绑定端口,而客户端不需要,客户端只需要向服务器端的监听端口发送消息就可以了,也只能由客户端向服务器端发送消息。程序的实现如下;

    服务器端

    1.初始化

    WSAStartup(MAKEWORD(2,2),&wsad);

    2.创建用于监听的socket     s=socket(AF_INET,SOCK_DGRAM,0);

    3.绑定一个地址端口     SOCKADDR_IN udpAdress,sender;     int senferAddSize=sizeof(sender);     udpAdress.sin_family=AF_INET;     udpAdress.sin_port=htons(11112);     udpAdress.sin_addr.s_addr=inet_addr("127.0.0.1");     bind(s,(SOCKADDR*)&udpAdress,sizeof(udpAdress));

    4.就可以调用recvfrom这个无连接的的接收函数接收数据,这个函数是阻塞的。无连接的协议不保证数据传输的可靠性,而且一次传输的数据量是有限的     ret=recvfrom(s,data,1000,0,(SOCKADDR*)&sender,&senferAddSize);

    5.结束后关闭socket和清理

    客户端

    1.初始化

    WSAStartup(MAKEWORD(2,2),&wsad);

    2.创建一个socket,但是不用绑定端口     usocket=socket(AF_INET,SOCK_DGRAM,0);

    3.使用无连接的发送函数sendto向指定地址发送数据       sendto(usocket,data(),totalbyte,0,(SOCKADDR*)&dstAdd,dstAddrSize);

    4.关闭、清理     closesocket(usocket);     WSACleanup();

    最新回复(0)