c语言网络通信tcp链接,C语言实现TCP链接

这两天复习了很多有关Windows平台和Linux平台的Socket编程知识,以前曾经写过一篇博文,示范过怎么使用C语言实现TCP链接,可是那篇文章写得很随意,因此如今我决定要重写这篇文章,既是为了总结这两天学到的知识,也为了给往后我写代码一个参考。linux

下面我用给出两份C语言代码来实现TCP链接,采用边写代码边解释的办法讲解这些程序,越复杂的代码越难看懂,所以我将给出最简洁的代码、包含最少的头文件来实现一个只发出一句话就随即关闭的程序。编程

首先总结一下TCP的链接过程:小程序

服务端:windows

建立一个Socket    「 socket() 」服务器

建立并初始化本机地址结构体    「 struct sockaddr_in 」网络

绑定Socket和地址结构体     「 bind() 」多线程

监听链接     「 listen() 」socket

接受链接     「 accept() 」函数

开始自由通讯     「 Linux: read()/write() 」 「 Windows: recv()/send() 」spa

关闭Socket      「 close() 」

客户端:

建立一个Socket     「 socket() 」

建立并初始化服务器地址结构    「 struct sockaddr_in 」

链接服务器      「 connect() 」

开始自由通讯        「 Linux: read()/write() 」「 Windows: recv()/send() 」

关闭Socket          「close() 」

代码:

服务端(Windows平台):

#include

#include

int main(){

//启动Socket前的初始化

WSADATA wsaData;

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

/*在windows平台上使用Socket编程前 *必须* 先调用WSAStartup()函数初始化一些工做,

是关于ws2_32.dll调用的初始化,ws2_32.dll提供了实现网络链接必要的函数,

当程序运行结束之后须要调用WSACleanup()来清理、释放资源,

若是以linux为服务器,则不须要这项工做*/

//建立SOCKET

SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

/*在一次通讯中,通讯的双方每边都会有一个SOCKET,用于标识本身

SOCKET这东西在我看来,就跟一个文件流没什么差异,

在linux上咱们能够调用write()向要通讯的对方的SOCKET中写入数据,

对方能够调用read()从他本身的SCOKET中读取数据咱们刚发送的数据,

就像操做一个普通文件同样,只不过这个"文件"是储存在另外一台电脑上而已,

因此把它理解成一个通讯的通道就行了*/

//绑定本机的地址到SOCKET

//首先须要构造一个地址结构体来储存咱们本身的IP和端口

//这个结构体的具体描述在网上有不少介绍,也能够打开winsock2.h头文件查看详细信息,这里就很少说了

struct sockaddr_in serverAddr;

serverAddr.sin_family = AF_INET; //TCP协议这么写就行了

serverAddr.sin_port = htons(1187); //端口号,htons()这个函数你们有必要去了解一下

serverAddr.sin_addr.s_addr = INADDR_ANY; //本机的IP地址,上次我在这里填了127.0.0.1,

//结果局域网里的其余机器都链接不上,因而改为了这样才能够

//这样就把本机的IP和SOCKET绑定起来了

bind(serverSocket,(struct sockaddr*)&serverAddr,sizeof(serverAddr));

//设置监听参数

listen(serverSocket,1);

/*第二个参数的意思不是最多能接受多少个链接,而是同时能处理几个主机的链接请求,

这里设置为1,假设服务器上线之后,同时有两台主机请求链接,

那么就最多只会处理一个链接,而另外一台主机只能链接失败

值得注意的是,程序运行到这里并不会中止下来,监听端口,等待链接。

我以前一直觉得服务器等待链接是在这里发生的,真正等待链接的函数是下面的accept() */

//接受链接

struct sockaddr_in clientAddr;

int clientAddrSize = sizeof(struct sockaddr_in);

SOCKET clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrSize);

/*这只是个简单示例,因此只用了一个客户SOCKET,也就是说只要有一台主机链接进来,

咱们就不会再处理新的链接,而真实的服务器通常都是用多线程来接受客户链接的,

每接收到一个新的链接,就建立一个新线程来跟客户端交互。

程序运行到accept()函数这里就会阻塞住,直到有新的链接才会继续运行下去,

accpet()函数须要一个sockaddr_in结构图做为参数,

函数调用完毕后这个结构体里就储存着客户端的IP地址,

accpet()函数返回的是新链接的SOCKET,咱们下面跟对方交互就用这个SOCKET。*/

//向客户端发送数据

char str[] = "Hello,friend!";

send(clientSocket, str, sizeof(str), 0);

/*发送数据很简单,参数基本都能理解,最后一个参数我尚未仔细研究过,只知道通常置0就行了*/

//关闭套接字

closesocket(serverSocket);

closesocket(clientSocket);

//首尾呼应

WSACleanup();

return 0;

}

客户端(Linux平台):

#include

#include

#include

int main(){

//构造socket

int mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

printf("Socket: %d\n",mySocket);

//链接服务器,用的是connect()函数,调用须要一个sockaddr_in结构体

struct sockaddr_in serverAddr;

serverAddr.sin_family = AF_INET;

serverAddr.sin_port = htons(1187);

serverAddr.sin_addr.s_addr = inet_addr("192.168.0.XXX"); //这里填上服务器的IP地址

connect(mySocket, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr));

//接收服务器发送的数据

char buffer[40];

read(mySocket, buffer, sizeof(buffer)-1);

printf("Message form server: %s\n", buffer);

//关闭链接

close(mySocket);

return 0;

}

这只是一个简单的、不完整的、有BUG的小程序,还有不少没有作到位的地方,望高手指点。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值