TCPIP大作业 基于Socket的网络通信

更新时间:2023-08-15 05:34:01 阅读量: 人文社科 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

基于Socket的网络通信 ,含有可实现代码以及结果截图

编号

TCP/IP协议与网络编程

期末大作业

题目: 基于Socket的网络通信

物联网工程 学院 计算机科学与技术 专业

学 号

学生姓名 任课教师

二〇一六年五月

基于Socket的网络通信 ,含有可实现代码以及结果截图

摘要

摘 要

此TCP/IP课程设计实现了基于TCP的客户/服务器通信程序,具体实验过程通过有连接服务为主体,无连接服务为辅并利用事件对象I/O管理来实现。客户机具有注册,登陆,单聊,私聊,退出等功能。

关键词:TCP/IP、有连接、、通信程序

基于Socket的网络通信 ,含有可实现代码以及结果截图

目录

目录

第1章 总体设计 ................................................................................................................................................ 2 第2章 客户端设计 ............................................................................................................................................ 4

2.1 发送端设计 ........................................................................................................................................... 4

2.11 流程图 ......................................................................................................................................... 4 2.12 代码 ............................................................................................................................................. 5 2.2接收端设计 .......................................................................................................................................... 12

2.21 流程图 ....................................................................................................................................... 12 2.22 代码 ........................................................................................................................................... 12

第3章 服务器设计 .......................................................................................................................................... 18

3.1 流程图 ................................................................................................................................................. 18 3.2 代码 ..................................................................................................................................................... 18 第4章 运行结果 .............................................................................................................................................. 25

基于Socket的网络通信 ,含有可实现代码以及结果截图

第1章 总体设计

1、基本通信协议选取

TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。而UDP则不为IP提供可靠性、流控或差错恢复功能。TCP对应的是可靠性要求高的应用,而UDP对应的则是可靠性要求低、传输经济的应用。

本次实验基于TCP/IP协议利用事件对象I/O管理实现基本的聊天功能,包括注册,登录,群聊,私聊及在线人数统计。

2、通信过程设计

2.1客户端设计

a.本地服务器

主要功能:

1)接收远程服务器转发的消息并显示消息。 b.本地客户端

主要功能:

1)发送建立TCP连接的请求操作;

2)发送注册信息,登陆消息及退出请求;

3)发送群聊消息,私聊消息,在线人数统计及退出请求。

2.2服务器端设计

a.远程服务端

主要功能:

1)监听客户端的连接请求;

2)提供注册服务,验证登陆请求和验证功能; 3)查看在线人数,发送在线状态; 4)发送群聊消息及私聊消息。

基于Socket的网络通信 ,含有可实现代码以及结果截图

3、程序流程图

基于Socket的网络通信 ,含有可实现代码以及结果截图

第2章 客户端设计

2.1 发送端设计

2.11 流程图

基于Socket的网络通信 ,含有可实现代码以及结果截图

2.12 代码

#include <winsock2.h> #include <stdlib.h> #include <stdio.h>

#pragma comment(lib, "Ws2_32.lib") #define BUFFER_SIZE 1024

void MySendMessage(SOCKET sSocket,char *response,int responseLen); int main(int argc, char **argv) { WSADATA wsaData; sockaddr_in ser,cli; SOCKET sClient,wchysClient; int iLen,wchyiLen; int iRecv; char send_buf[1000]; char recv_buf[BUFFER_SIZE]; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup()\n"); return 0; } printf("手动连接模式中....\n"); char szServer[256]; //连接的服务器地址,IP地址 printf("请输入即将连接的服务器IP地址:"); gets(szServer); ser.sin_family = AF_INET; ser.sin_port = htons(5050); ser.sin_addr.s_addr = inet_addr(szServer); char user[20],password[20]; char str[100],str1[100],wchystr[100]; bool hasLogin=false; //只能绑定一次,开始放在了循环里,555 wchysClient=socket(AF_INET,SOCK_DGRAM,0); if(wchysClient==INVALID_SOCKET){printf("socket()Faild:%d\n",WSAGetLastError());ret

基于Socket的网络通信 ,含有可实现代码以及结果截图

urn 0;} cli.sin_family=AF_INET; cli.sin_port=htons(5053); cli.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(wchysClient,(LPSOCKADDR)&cli,sizeof(cli))==SOCKET_ERROR) {printf("bind()Faild:%d\n",WSAGetLastError());return 0;} wchyiLen=sizeof(cli); memset(recv_buf,0,sizeof(recv_buf)); sClient = socket(AF_INET, SOCK_STREAM, 0); if (sClient == INVALID_SOCKET) { printf("socket()\n"); return 0; } if (connect(sClient, (sockaddr*)&ser, sizeof(ser)) == INVALID_SOCKET) { printf("socket()\n"); return 0; } else { bool hasLogin=false; while(!hasLogin){ printf("--------------------------------\n"); printf("0.注册\n"); printf("1.登陆\n"); printf("2.退出\n"); printf("请输入相应的数字:\n>"); scanf("%s",&str); switch(str[0]) { case '0': printf("用户名:"); scanf("%s",user); printf("密 码:"); scanf("%s",password);

基于Socket的网络通信 ,含有可实现代码以及结果截图

strcpy(send_buf,"0"); strcat(send_buf,user); strcat(send_buf,"@");

strcat(send_buf,password);

MySendMessage(sClient, send_buf, sizeof(send_buf));

break;

case '1': printf("用户名:"); scanf("%s",user); printf("密 码:"); scanf("%s",password); strcpy(send_buf,"1"); strcat(send_buf,user); strcat(send_buf,"@"); strcat(send_buf,password); MySendMessage(sClient, send_buf, sizeof(send_buf));

iRecv=recvfrom(wchysClient,recv_buf,BUFFER_SIZE,0,(SOCKADDR*)&cli,&wchyiLen); if(iRecv==SOCKET_ERROR) {printf("recvfrom()Faild:%d\n",WSAGetLastError());return 0;} else if(iRecv==0) break; else {// 接收到了正确数据 printf("recv:%s\n",recv_buf); } if(recv_buf[0]=='@'&&recv_buf[1]=='@'){ hasLogin=0; system("cls"); printf("登录失败!请重新登录或注册后登录^_^\n"); } if(recv_buf[0]=='*'&&recv_buf[1]=='*'){ hasLogin=0; system("cls"); printf("已经在其他地方登陆\n");

基于Socket的网络通信 ,含有可实现代码以及结果截图

printf("登录失败!请重新选择用户登录或注册后登录^_^\n");

}

if(recv_buf[0]=='#'&&recv_buf[1]=='#'){ sizeof(send_buf));

hasLogin=1; system("cls"); printf("登录成功^_^\n"); bool wchyhasLogin=false; while(!wchyhasLogin){ printf("--------------------------------\n"); printf("0.群聊\n"); printf("1.单聊\n"); printf("2.在线用户\n"); printf("3.退出\n"); printf("请输入相应的数字:\n>"); scanf("%s",&wchystr); switch(wchystr[0]) { case '0': wchyhasLogin=1; printf("输入exit退出。\n"); printf("--------------------------------\n"); while(wchyhasLogin) { printf(">"); scanf("%s",&str); if(strcmp(str,"exit")!=0) { strcpy(send_buf,"2"); strcat(send_buf,user); strcat(send_buf,"@"); strcat(send_buf,str); MySendMessage(sClient, } else { system("cls"); wchyhasLogin=0; }

}

send_buf,

基于Socket的网络通信 ,含有可实现代码以及结果截图

break; case '1': wchyhasLogin=1; printf("请输入单聊对象的用户名:"); scanf("%s",&str1); strcpy(send_buf,"5"); strcat(send_buf,str1); strcat(send_buf,"@"); strcat(send_buf,user); strcat(send_buf,"*"); strcat(send_buf,"__Welcome__To__Single__Chat..."); MySendMessage(sClient, send_buf, sizeof(send_buf));

iRecv=recvfrom(wchysClient,recv_buf,BUFFER_SIZE,0,(SOCKADDR*)&cli,&wchyiLen); if(iRecv==SOCKET_ERROR) {printf("recvfrom()Faild:%d\n",WSAGetLastError());return 0;} else if(iRecv==0) break; else {// 接收到了正确数据 //printf("recv:%s\n",recv_buf); } if(recv_buf[0]=='^'&&recv_buf[1]=='^'){ wchyhasLogin=0; system("cls"); printf("单聊对象不存在,退出了单聊模式\n"); } if(recv_buf[0]=='&'&&recv_buf[1]=='&'){ wchyhasLogin=0; system("cls"); printf("单聊对象未在线,退出了单聊模式\n"); } if(recv_buf[0]=='%'&&recv_buf[1]=='%'){ printf("输入exit退出。\n"); printf("--------------------------------\n"); while(wchyhasLogin) { printf(">"); scanf("%s",&str);

基于Socket的网络通信 ,含有可实现代码以及结果截图

if(strcmp(str,"exit")!=0) sizeof(send_buf));

{ strcpy(send_buf,"5"); strcat(send_buf,str1); strcat(send_buf,"@"); strcat(send_buf,user); strcat(send_buf,"*"); strcat(send_buf,str); MySendMessage(sClient,

send_buf,

}

else { system("cls"); wchyhasLogin=0; } } } break; case '2': strcpy(send_buf,"4"); strcat(send_buf,user); strcat(send_buf,"@"); strcat(send_buf,str); MySendMessage(sClient, send_buf, sizeof(send_buf)); system("cls"); break; case '3': strcpy(send_buf,"3"); strcat(send_buf,user); strcat(send_buf,"@"); MySendMessage(sClient, send_buf, sizeof(send_buf)); hasLogin=0; wchyhasLogin=1; system("cls"); break; default: system("cls"); printf("请输入正确信息\n"); break;

}

基于Socket的网络通信 ,含有可实现代码以及结果截图

} } break; case '2': exit(0); break; default: system("cls"); printf("请输入正确信息"); } } } system("PAUSE"); closesocket(sClient); WSACleanup(); return 0; }

void MySendMessage(SOCKET sSocket,char *response,int responseLen) { int iSend; iSend=send(sSocket,response,responseLen,0); if(iSend==SOCKET_ERROR) { printf("send()Failed.:%d\n",WSAGetLastError()); } else if(iSend==0) ; else { //printf("send() succeeded !\n"); printf("----------------------\n"); } }

基于Socket的网络通信 ,含有可实现代码以及结果截图

2.2接收端设计

2.21 流程图

2.22 代码

#include<WinSock2.h> #include<stdio.h> #include<stdlib.h> #include<string.h>

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

#define DEFAULT_PORT 5051//FOR RECV #define BUFFER_LENGTH 1000

void MySendMessage(SOCKET sSocket,char *response,int responseLen, struct sockaddr* cli,int

基于Socket的网络通信 ,含有可实现代码以及结果截图

cliLen);

void main() {

while(1) {

int iPort=DEFAULT_PORT; WSADATA wsaData;

SOCKET sSocket,wchysSocket; int iLen,wchyiLen; int iSend; int iRecv;

char send_buf[1000];

char recv_buf[BUFFER_LENGTH]; struct sockaddr_in ser,cli,wchy; printf("----------------------\n"); printf("cServer Waiting\n"); printf("----------------------\n");

if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) {printf("Failed to load Winsock.\n");return;} sSocket=socket(AF_INET,SOCK_DGRAM,0);

if(sSocket==INVALID_SOCKET){printf("socket()Faild:%d\n",WSAGetLastError());return;} ser.sin_family=AF_INET; ser.sin_port=htons(iPort);

ser.sin_addr.s_addr=htonl(INADDR_ANY);

if(bind(sSocket,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR) {printf("bind()Faild:%d\n",WSAGetLastError());return;} iLen=sizeof(cli);

memset(recv_buf,0,sizeof(recv_buf));

基于Socket的网络通信 ,含有可实现代码以及结果截图

iRecv=recvfrom(sSocket,recv_buf,BUFFER_LENGTH,0,(SOCKADDR*)&cli,&iLen); if(iRecv==SOCKET_ERROR)

{printf("recvfrom()Faild:%d\n",WSAGetLastError());return;} else if(iRecv==0) break; else

{// 接收到了正确数据

//printf("[+]%s\n",recv_buf);

//控制信息的种类有00 01 10 11 12 20 21 30 31

//00注册成功 01 注册失败 10登陆成功 11.12表示登陆失败 20表示一次成功会

switch(recv_buf[0]) {

case '0':

if(recv_buf[1]=='0')printf("注册成功\n"); else printf("注册失败\n"); break;

话 21表示错误会话 30表示成功推出 31表示错误推出

case '1':

if(recv_buf[1]=='0') { }

else if(recv_buf[1]=='@') {

printf("已经在其他地方登陆\n"); wchy.sin_family=AF_INET; wchy.sin_port=htons(5053);

wchy.sin_addr.s_addr=inet_addr("127.0.0.1"); wchysSocket=socket(AF_INET,SOCK_DGRAM,0); if(wchysSocket==INVALID_SOCKET)

{printf("socket()Failed:%d\n",WSAGetLastError());return;}

printf("登陆成功\n"); wchy.sin_family=AF_INET; wchy.sin_port=htons(5053);

wchy.sin_addr.s_addr=inet_addr("127.0.0.1"); wchysSocket=socket(AF_INET,SOCK_DGRAM,0); if(wchysSocket==INVALID_SOCKET)

{printf("socket()Failed:%d\n",WSAGetLastError());return;} wchyiLen=sizeof(wchy); strcpy(send_buf,"##");

MySendMessage(wchysSocket,send_buf,sizeof(send_buf),(struct

sockaddr*)&wchy,wchyiLen);

基于Socket的网络通信 ,含有可实现代码以及结果截图

case '2':

printf("[群聊]%s\n",recv_buf+2); break;

printf("在线用户列表:%s\n",recv_buf+2); break;

printf("[单聊]"); wchy.sin_family=AF_INET; wchy.sin_port=htons(5053);

wchy.sin_addr.s_addr=inet_addr("127.0.0.1"); wchysSocket=socket(AF_INET,SOCK_DGRAM,0); if(wchysSocket==INVALID_SOCKET)

{printf("socket()Failed:%d\n",WSAGetLastError());return;}

wchyiLen=sizeof(wchy); strcpy(send_buf,"%%");

MySendMessage(wchysSocket,send_buf,sizeof(send_buf),(struct printf("%s\n",recv_buf+2); break;

} break;

wchyiLen=sizeof(wchy); strcpy(send_buf,"@@");

MySendMessage(wchysSocket,send_buf,sizeof(send_buf),(struct

} else{

printf("登陆失败\n"); wchy.sin_family=AF_INET; wchy.sin_port=htons(5053);

wchy.sin_addr.s_addr=inet_addr("127.0.0.1"); wchysSocket=socket(AF_INET,SOCK_DGRAM,0); if(wchysSocket==INVALID_SOCKET)

{printf("socket()Failed:%d\n",WSAGetLastError());return;} wchyiLen=sizeof(wchy); strcpy(send_buf,"**");

MySendMessage(wchysSocket,send_buf,sizeof(send_buf),(struct

sockaddr*)&wchy,wchyiLen);

sockaddr*)&wchy,wchyiLen);

case '4':

case '5':

sockaddr*)&wchy,wchyiLen);

case '6':

基于Socket的网络通信 ,含有可实现代码以及结果截图

}

}

}

}

{ }

else if(recv_buf[1]=='1') { } break;

printf("单聊对象未在线\n"); wchy.sin_family=AF_INET; wchy.sin_port=htons(5053);

wchy.sin_addr.s_addr=inet_addr("127.0.0.1"); wchysSocket=socket(AF_INET,SOCK_DGRAM,0); if(wchysSocket==INVALID_SOCKET)

{printf("socket()Failed:%d\n",WSAGetLastError());return;} wchyiLen=sizeof(wchy); strcpy(send_buf,"&&");

MySendMessage(wchysSocket,send_buf,sizeof(send_buf),(struct printf("单聊对象不存在\n"); wchy.sin_family=AF_INET; wchy.sin_port=htons(5053);

wchy.sin_addr.s_addr=inet_addr("127.0.0.1"); wchysSocket=socket(AF_INET,SOCK_DGRAM,0); if(wchysSocket==INVALID_SOCKET)

{printf("socket()Failed:%d\n",WSAGetLastError());return;} wchyiLen=sizeof(wchy); strcpy(send_buf,"^^");

MySendMessage(wchysSocket,send_buf,sizeof(send_buf),(struct

sockaddr*)&wchy,wchyiLen);

sockaddr*)&wchy,wchyiLen);

closesocket(sSocket); WSACleanup();

void MySendMessage(SOCKET sSocket,char *response,int responseLen, struct sockaddr* cli,int cliLen) {

int iSend;

基于Socket的网络通信 ,含有可实现代码以及结果截图

}

iSend=sendto(sSocket,response,responseLen,0,(SOCKADDR*)cli,cliLen);

// iSend=sendto(sClient,send_buf,sizeof(send_buf),0,(struct sockaddr*)&ser,iLen); if(iSend==SOCKET_ERROR) { }

else if(iSend==0) ; else { }

//printf("sendto() succeeded !\n"); //printf("----------------------\n");

printf("sendto()Failed.:%d\n",WSAGetLastError());

sockaddr * to , int tolen ) ;

基于Socket的网络通信 ,含有可实现代码以及结果截图

第3章 服务器设计

3.1 流程图

3.2 代码

#include <winsock2.h> #include <stdlib.h> #include <stdio.h>

#pragma comment(lib,"ws2_32.lib") #include"init.h" #include"deal.h" //

UserData *userdata[MaxUser]; int userdatap=-1; #define BUFFER_SIZE 2048

void CompressArrays(WSAEVENT events[], SOCKET sockets[], DWORD *total, int index) {

for (size_t i = index + 1; i < *total; i++)

基于Socket的网络通信 ,含有可实现代码以及结果截图

{ events[i - 1] = events[i];

}

*total--;

}

int main(int argc, char **argv) { InitData(userdata,MaxUser,userdatap); char response[BUFFER_LENGTH]; WSADATA wsaData;

char buffer[BUFFER_SIZE]; sockaddr_in InternetAddr;

//客户地址

struct sockaddr_in cli;

struct sockaddr_in cliArray[WSA_MAXIMUM_WAIT_EVENTS]; int iLen;

iLen=sizeof(cli); //udp发送 SOCKET sSocket; struct sockaddr_in ser; char send_buf[]="udp!"; SOCKET sClient;

SOCKET SocketArray[WSA_MAXIMUM_WAIT_EVENTS]; WSANETWORKEVENTS NetworkEvents; WSAEVENT NewEvent;

WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS]; SOCKET Accept, Listen; DWORD EventTotal = 0; DWORD Index;

if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { printf("WSAStartup()\n"); return 0;

}

// 创建一个流式套接口

Listen = socket(AF_INET, SOCK_STREAM, 0); InternetAddr.sin_family = AF_INET;

InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY); InternetAddr.sin_port = htons(5050);

if (bind(Listen, (PSOCKADDR)&InternetAddr, sizeof(InternetAddr)) SOCKET_ERROR)

{

printf("bind()\n");

==

本文来源:https://www.bwwdw.com/article/5a5j.html

Top