欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

网络编程——socket @[TOC]( 基于tcp协议的收发聊天室

程序员文章站 2022-03-04 22:15:58
...

网络编程——socket @[TOC]( 基于tcp协议的收发聊天室
初学网络编程一周不到时间,根据《TCP\IP网络编程》一书的理解 初步编写了一个基于win系统 send()和recv()函数的聊天窗口 代码记录如下
(vs2017)

//服务器端
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>
//#define _WINSOCK_DEPRECATED_NO_WARNINGS
void ErrorHandling(char* message);
int main(int argc ,char *argv[])
{
	WSADATA wsaData;//win中使用套接字必须
	SOCKET hServSock, hClntSock;
	SOCKADDR_IN servAddr, clntAddr;

	int szClntAddr;//accept中需使用
	//char message[] = "hello World";
	if (argc != 2)
	{
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		ErrorHandling("WSAStartup() error!");
	//创建套接字
	hServSock = socket(PF_INET, SOCK_STREAM, 0);
	if (hServSock == INVALID_SOCKET)
		ErrorHandling("socket() error");
	//地址信息初始化
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;//地址族 ,ipv4地址族
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);//32位ip地址信息
	servAddr.sin_port = htons(atoi(argv[1]));//端口号 16位端口号
	//分配地址信息
	if (bind(hServSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
		ErrorHandling("bind() error");
	if(listen(hServSock,5)== SOCKET_ERROR)//int listen(int sock,int backlog)
		ErrorHandling("listen() error");//此时hServSock才为服务器端套接字

	printf("this is serve:\n");
	szClntAddr = sizeof(clntAddr);
	hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr);//第三个参数存有变量长度的地址
	if(hClntSock==INVALID_SOCKET)
		ErrorHandling("accept() error");

	//实现消息收发  
	while (1)
	{
		char rec_message[100];
		char send_message[100];
		int str_long;
		str_long = recv(hClntSock, rec_message, 100, 0);//接收 并记录接受字符串的长度
		rec_message[str_long] = 0;//防止乱码
		printf("Message from clnt: %s \n", rec_message);
		
		scanf("%s", send_message);
		if (!strcmp(send_message,"q\n")|| !strcmp(send_message, "Q\n"))
			break;
		send(hClntSock, send_message, sizeof(send_message), 0);
	}
	closesocket(hServSock);
	closesocket(hClntSock);
	WSACleanup();
	system("pause");
	return 0;

}

void ErrorHandling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}
//客户端
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<winsock2.h>

void ErrorHandling(char *message);

int main(int argc, char* argv[])
{
	WSADATA wsaData;
	SOCKET hSocket;
	SOCKADDR_IN servAddr;

	char message[30];
	//int strlen = 0;
	int idx = 0, readlen = 0;
	if (argc != 3)
	{
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		ErrorHandling("WSAStartup() error!");

	hSocket = socket(PF_INET, SOCK_STREAM, 0);

	if (hSocket == INVALID_SOCKET)
		ErrorHandling("socket() error");

	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = inet_addr(argv[1]);
	servAddr.sin_port = htons(atoi(argv[2]));
	//调用connect()函数,连接到服务器端
	if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
		ErrorHandling("connect() error!");
	printf("this is clint :\n");

	//客户端实现消息收发
	while(1)
	{
		char send_message[100];
		int str_long;
		scanf("%s", send_message);
		//!strcmp(message, "q\n") || !strcmp(message, "Q\n")
		if (strcmp(send_message, "q\n") == 0 || strcmp(send_message, "Q\n") == 0)
			break;
		send(hSocket, send_message, strlen(send_message), 0);

		str_long = recv(hSocket, message, strlen(message), 0);
		message[str_long] = 0;
		printf("Message from server: %s \n", message);

		//printf("Function read call count:%d \n", strlen);
	}
	closesocket(hSocket);
	WSACleanup();
	system("pause");
	return 0;
}

void ErrorHandling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

以上代码大多为套接字的搭建,防止丢失故记录如上。

相关标签: TCP/IP