TCP/IP网络编程学习之路二

本文介绍在Windows环境下如何进行网络编程,包括服务器端和客户端的基本框架搭建。通过具体代码示例展示了如何使用socket函数创建套接字,bind函数绑定IP地址和端口,listen函数监听连接请求,accept函数接收客户端连接,以及connect函数发起连接。

基于Windows下的网络编程:

网络编程基本上都有服务器端和客户端,这两个端所实现的方法是不一样的。

服务器端的一般框架

  1. 用socket()函数创建一个套接字,并建立资源所使用的资源 SOCKET socket(int af,int type,int protocol) 
  2. 用bind()函数绑定套接字,并为其分配IP 地址和端口号 int PASCAL FAR bind( SOCKET s,const struct sockaddr FAR *name,int namelen )
  3. 用listen()函数监听是否有客户端想连接 int PASCAL FAR listen( SOCKET s, int backlog )
  4. 用accept()函数来接收客户端的连接请求, 同时创建一个新的套接字来和客户端通信    SOCKET PASCAL FAR accept(SCOKET s,struct sockaddr FAR *addr,int FAR *addrlen);
客户端的一般框架

  1. 用socket()函数创建一个套接字,并建立资源所使用的资源 SOCKET socket(int af,int type,int protocol) 
  2. 用connect()函数来连接服务器int PASCAL FAR connect( SOCKET s,const struct sockaddr FAR *name,int namelen );
只有我们写完这些步骤,服务器和客户端才有可能联通,【注意】服务器通过accept()生成的套接字和客户端生成的套接字来通信!

接下来解释函数参数的意思

SOCKET PASCAL FAR socket( int af,int type,int protocol );

af 表示套接字中使用的协议族信息, type表示套接字的类型(面向连接的或者面向无连接的),protocol表示计算机间通信中使用的协议信息(一般写0);

int PASCAL FAR bind( SOCKET s,const struct sockaddr FAR *name,int namelen );

s 是socket()函数创建的套接字 name 是Socket的位址值,其格式为 struct sockaddr { u_short sa_family; char sa_data[14]; }; namelen 是name的长度

int PASCAL FAR listen( SOCKET s, int backlog );

s是socket()函数创建的套接字, backlog是最多允许的连接数。

SOCKET PASCAL FAR accept(SCOKET s,struct sockaddr FAR *addr,int FAR *addrlen);

s 是socket()函数创建的套接字, addr 存放来连接的彼端的位址; addrlen addr的长度,这个函数会返回新的套接字!

int PASCAL FAR connect( SOCKET s,const struct sockaddr FAR *name,int namelen );

s是客户端通过socket()函数创建的套接字,name 是此 Socket 想要连接的对方位址 namelen 是name的长度;

服务器的基本框架

#include <iostream>
#include <WinSock2.h>
#include <cstdlib>
#include <cstring>

#pragma comment(lib, "ws2_32.lib")
using namespace std;
const int MAXLENGTH = 4096;



int main()
{
	WSADATA wsaData;
	int result = WSAStartup(MAKEWORD(2,2), &wsaData);
	if(result != NO_ERROR)
	{
		cerr << "init winsock failured" << endl;
		exit(1);
	}

	SOCKET serversocket;

	serversocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(serversocket == INVALID_SOCKET)
	{
		cout << "建立socket失败" << WSAGetLastError() << endl;
		system("pause");
		return -1;
	}

	sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	server.sin_port = htons(6800);

	result = bind(serversocket, (struct sockaddr *)&server, sizeof(server));
	if(result == SOCKET_ERROR)
	{
		cout << "绑定失败" << endl;
		system("pause");
		return -1;
	}

	result = listen(serversocket, 5);
	if(result == SOCKET_ERROR)
	{
		cout << "监听失败" << endl;
		system("pause");
		return -1;
	}

	char recvbuf[1024];
	struct sockaddr_in client;
	int length =sizeof(client);
	SOCKET acceptsock = accept(serversocket, (struct sockaddr *)&client, &length);
	if(acceptsock == INVALID_SOCKET)
	{
		cout << "接受失败" << endl;
		system("pause");
		return -1;
	}

	result = recv(acceptsock, recvbuf, strlen(recvbuf), 0);
	if(result == SOCKET_ERROR)
	{
		cout << "接收失败" << endl;
		system("pause");
		return -1;
	}
	
	cout << recvbuf << endl;
	cin >> recvbuf;
	result = send(acceptsock, recvbuf, strlen(recvbuf), 0);
	if(result == SOCKET_ERROR)
	{
		cout << "发送失败" << endl;
		system("pause");
		return -1;
	}
	
	closesocket(acceptsock);
	closesocket(serversocket);
	WSACleanup();

	system("pause");
	return 0;
}


客户端的基本框架

#include <iostream>
#include <WinSock2.h>
#include <cstring>

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

using namespace std;

int main()
{
	WSADATA wsaData;
	int ret = WSAStartup(MAKEWORD(2,2), &wsaData);
	if(ret != 0)
	{
		cout << "初始化win失败"  << endl;
		system("pause");
		return -1;
	}

	SOCKET clientsocket;
	clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(clientsocket == SOCKET_ERROR)
	{
		cout << "创建socket失败" << endl;
		system("pause");
		return -1;
	}

	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	server.sin_port = htons(6800);

	ret = connect(clientsocket, (struct sockaddr *)&server, sizeof(server));
	if(ret == SOCKET_ERROR)
	{
		cout << "连接失败" << GetLastError() << endl;
		system("pause");
		return -1;
	}

	char buffer[1024];
	cin >> buffer;
	ret = send(clientsocket, buffer, strlen(buffer), 0);
	if(ret == SOCKET_ERROR)
	{
		cout << "发送失败" << GetLastError() << endl;
		system("pause");
		return -1;
	}
	ret = recv(clientsocket, buffer, strlen(buffer), 0);
	if(ret == SOCKET_ERROR)
	{
		cout << "接收失败" << GetLastError() << endl;
		system("pause");
		return -1;
	}
	cout << buffer << endl;

	closesocket(clientsocket);
	WSACleanup();
	system("pause");
	return 0;
}




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值