SOCKET建立步骤

C语言   粗体字公共部分  斜体字为服务器 其余为客户端

服务器客户端

#include

#include

#pragma comment(lib,"WS2_32.lib")

int main(int argc, char* argv[])

{

WSADATA wsaData;

WORD sockVersion = MAKEWORD(2,0);//指定版本号,使用WINSOCK2版本

::WSAStartup(sockVersion, &wsaData);//载入winsock的dll启动函数

第一个参数是WINSOCK版本号,第二个参数是指向WSADATA的指针

SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

//创建套接字基于TCP,第一个是协议域,AF_IMET决定了要用IPV4地址(32位)与端口号(16位)的组合,把ipv4地址和端口号组合赋给socket;第二个指定socket的类型;第三个指定协议,此处对应TCP传输协议,简单来说既是(使用TCP/IP协议;传输过程使用TCP;不适用其他特殊协议)

if(s == INVALID_SOCKET)

{

printf("error");

::WSACleanup();

//终止函数,清理,释放资源应用程序在完成对请求的socket库的使用后WSAClanup,

清除套接字资

函数来接触与socket库的绑定并且释放socket库所占用的系统资源

return 0;

}

sockaddr_in sin;//socket中装入地址信息

sockaddr_in servAddr;//定义套接字地址

sin.sin_family = AF_INET;//sin.family表示地址族,对于IP地址,sin_family将一直是AF_INET

servAddr.sin_family = AF_INET;//储存IP地址,INADDR_ANY就是制定地址为0.0.0.0的地址,

这个地址事实上表示不确定地址,或“所有地址”、“任意地址”

sin.sin_port = htons(8888);//端口号表示服务器监听的端口号使8888

servAddr.sin_port = htons(8888);//端口号表示客户端接受服务器8888端口号

sin.sin_addr.S_un.S_addr = INADDR_ANY;//储存地址,INADDR就是指定地址为

0.0.0.0的地址,这个地址事实上表示不确定地址,也就是所有的地址或任意地址

servAddr.sin_addr.S_un.S_addr = inet_addr("192.168.31.220");//本地IP地址,

inet_addr()将IP地址转为点分十进制的格式

//绑定socket,绑定地址及端口号

if(::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)

参数一:指定与那个套接字绑定

参数二:指定地址

参数三:确定恢复多少数据

{

printf("error");

::WSACleanup();//清理释放资源

return 0;

}

//bind函数把一个地址族中的特定地址赋给socket。第一个参数是socket描述字,通过socket创建,唯一标识一个socket。bind()函数就是将这个表述字绑定一个名字。第二个参数指向要绑定给socket的协议地址。第三个参数对应的是地址的长度。

为服务器端定义的这个监听的socket指定一个地址及端口(port),这样客户端才知道待会儿要

连接哪一个地址的哪个端口,为此我们要调用bind函数

//监听socket,监听客户端的连接请求

if(::listen(s, 2) == SOCKET_ERROR)//监听客户端请求

参数一:被listen函数调用的套接字

参数二:连接数量的上限

{

printf("error");

::WSACleanup();//释放资源

return 0;

}

//连接主动完成连接过程,三次握手协议,谁调用了connet函数谁就是先发送数据的一方

if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)//连接服务器

参数一:指定数据发送的套接字

参数二:指定数据发送的目的地址,也就是服务端地址

{

printf("error");

::WSACleanup(); //释放资源

return 0;

}

char buff[156];//缓冲区

int nRecv = ::recv(s, buff, 156, 0);//接收数据并打印到屏幕上

//不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。

第一个参数:指定接收端套接字描述符

第二个参数:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据

第三个参数:指明buf的长度

第四个参数:一般设置0

if(nRecv > 0)

{

buff[nRecv] = '\0';

printf("接受数据:%s",buff);

}

sockaddr_in remoteAddr;

int nAddrLen = sizeof(remoteAddr);

SOCKET client;

char szText[] = "peter\n";//缓冲区数据

while(1)循环接受连接请求

{accept默认会阻塞进程,直到有一个客户建立连接后返回,他返回的是一个新

可用的套接字,这个套接字是连接套接字

/*accept服务器端使用,调用函数进入阻塞状态,等待用户连接,如果没有客户端进行连接,程序就在这个地方。

不会看到后面。如果有客户端连接,那么程序就执行一次然后继续循环到这里等待。*/

client = ::accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen);

参数一:监听套接字,这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个端口号,而此时这个端口号正与这个套接字关联。当然客户不知道套接字这些细节,他只知道一个地址和一个端口号

参数二:这是一个结果参数,它用来接受一个返回值,这返回值指定客户端的地址。

//acc

if(client == INVALID_SOCKET)

{

printf("error");

continue;

}

printf("接受到一个连接:%s\r\n",inet_ntoa(remoteAddr.sin_addr));客户端IP

::send(client, szText, strlen(szText), 0); //发送数据,发送本地时间给客户端

//不论是客户还是服务器应用程序都用send函数来想TCP连接的另一端发送数据,

客户程序一般都用send函数向服务器发送请求,而服务器则通常用send函数

来向客户程序发送应答。

第一个参数:指定发送端套接字描述符

第二个参数指明一个存放应用程序要发送数据的缓冲区

第三个参数指明实际要发送的数据的字节数

第四个参数一般设置0

::closesocket(client);//关闭套接字,关闭连接

}

::closesocket(s);关闭套接字

::WSACleanup();

return 0;

}


2015.7.7

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • socket通信原理 socket又被叫做套接字,它就像连接到两端的插座孔一样,通过建立管道,将两个不同的进程之间...
    jiodg45阅读 4,860评论 0 1
  • 简介 Socket理论 Socket工作流程 核心函数讲解 服务的如何获取客户端的信息 字符串ip和网络二进制的转...
    第八区阅读 9,136评论 0 4
  • 原文地址:http://www.cnblogs.com/skynet/archive/2010/12/12/190...
    archyly阅读 4,695评论 0 8
  • 在炎热的夏天,我们都非常浮躁,而我遇到你,却清凉了一整个夏天。 第一次遇到你,阳光从窗口洒进来,刚好落到你的...
    小明姐姐阅读 3,034评论 0 0
  • 包厢中,男人女人们在谈笑风生,烟雾缭绕,她坐在角落的沙发上,一言不语,两杯酒下肚,头靠在沙发上,闭上眼睛,脑中闪过...
    草莓妈阅读 3,486评论 0 0

友情链接更多精彩内容