SOCKET通信流程

本文详细解析了Socket编程中服务器和客户端的通信流程,包括如何使用Winsock库进行初始化、创建套接字、绑定地址、监听连接、接受连接、收发数据以及关闭套接字等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义变量——获得WINSOCK版本——加载WINSOCK库——初始化——创建套接字 ——设置套接字选项——关闭套接字——卸载WINSOCK库——释放所有资源

整个程序架构分为两大部分,服务器端客户端。

服务器SOCKET程序流程

socket()→bind()→listen→accept()→recv()/send()→closesocket()

客户端:

socket→connect()→send()/recv()→closesocket()

服务器代码:

#include <winsock2.h>
#pragma comment(lib,"ws2_32")
#include <stdio.h>
int main(int argc, char* argv[])
{
WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 2);
//加载winsock库
if(WSAStartup(sockVersion, &wsaData) != 0)
   return 0;
// 创建套节字
SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sListen == INVALID_SOCKET)
{
   printf("socket error\n");
   return 0;
}
// 在sockaddr_in结构中装入地址信息
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(4500); // htons函数 将主机的无符号短整形数转换成网络
//字节顺序
sin.sin_addr.S_un.S_addr = INADDR_ANY;
// 使套接字和本地地址绑定
if(bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
   printf(" bind error \n");
   closesocket(sListen);
   return 0;
}
// 设置套接字进入监听模式
if(listen(sListen, 5) == SOCKET_ERROR)
{
   printf("listen error\n");
   closesocket(sListen);
   return 0;
}
// 循环接受客户的连接请求
sockaddr_in remoteAddr;
SOCKET sClient;
    int nAddrLen = sizeof(remoteAddr);
char revData[255];
while(TRUE)
{
   // 接受一个新连接
   sClient = accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen);
   //accept函数调用失败则继续等待连接。
   if(sClient == INVALID_SOCKET)
   {
    printf("accept() error");
    continue;
   }
   //打印出连接者的ip
   printf(" 接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));
   //直到收到有效数据时才打印出来
   int ret=recv(sClient,revData,255,0);
        if(ret>0)
   {
    //为了防止打印出错,把字符串结尾设成0x00
    revData[ret]=0x00;
    printf(revData);
   }
   char *buff="\r\n学习SOCKET编程\r\n";
        //发送数据
   send(sClient,buff,strlen(buff),0);
   // 关闭套接字句柄,结束会话
   closesocket(sClient);
}
closesocket(sListen);
WSACleanup();
return 0;
}

客户端代码:


#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib,"ws2_32")
#include <stdio.h>

int main(int argc, char* argv[])
{
WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 2);
//加载winsock库
if(WSAStartup(sockVersion, &wsaData) != 0)
   return 0;
// 创建套节字
    SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sClient == INVALID_SOCKET)
{
   printf("socket error\n");
   return 0;
}
// 在sockaddr_in结构中装入服务器端地址信息
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(4500);// htons函数 将主机的无符号短整形数转换成网络
                                 //字节顺序,4500端口为要连接服务器端的端口
servAddr.sin_addr.S_un.S_addr =inet_addr("127.0.0.1");//服务器端ip
//连接服务器端
if(connect(sClient,(sockaddr*)&servAddr,sizeof(servAddr))==SOCKET_ERROR)
{
   printf("connect error\n");
   closesocket(sClient);
   return 0;
}
char *buff="\r\nSOCKET编程,我来了\r\n";
    //发送数据
send(sClient,buff,strlen(buff),0);
char revData[255];
//直到收到有效数据时才打印出来
int ret=recv(sClient,revData,255,0);
if(ret>0)
{
   //为了防止打印出错,把字符串结尾设成0x00
   revData[ret]=0x00;
   printf(revData);
}
closesocket(sClient);
WSACleanup();
return 0;
}

为什么客户端不需要绑定IP地址和端口号

因为服务器是时时在监听有没有客户端的连接
如果服务器不绑定IP和端口的话,客户端上线的
时候怎么连到服务器呢,所以服务器要绑定IP和端口

面客户端就不需要了,客户端上线是主动向服务器发
出请求的,因为服务器已经绑定了IP和端口,所以
客户端上线的就向这个IP和端口发出请求,这时因为
客户开始发数据了(发上线请求),系统就给客户端分配
一个随机端口,这个端口和客户端的IP会随着上线请求
一起发给服务器,服务收到上线请求后就可以从中获起
发此请求的客户的IP和端口,接下来服务器就可以利用
获起的IP和端口给客户端回应消息了.

总之一句话,客户端是主动连接,而服务器是等待连接
所以结果就是你说的那样.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值