概述
实验要求:用两台计算机,一台是服务器另一台是客户端,运行结果要求在客户端把键入的字符串发送给服务器,服务器显示收到的字符串,并将字符串发回给客户端,客户端显示服务器发回的字符串。要求客户端能够多次发送字符串,服务器能够不断的接收并显示和发送。
Linux服务器:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <signal.h>
extern void sig_proccess(int signo);
#define PORT 8888 /*侦听端口地址*/
#define BACKLOG 2 /*侦听队列长度*/
int main(int argc, char*argv[])
{
int ss,sc; /*ss为服务器的socket描述符,sc为客户端的socket描述符*/
struct sockaddr_in server_addr; /*服务器地址结构*/
struct sockaddr_in client_addr; /*客户端地址结构*/
int err; /*错误值*/
pid_t pid; /*分叉的进行id*/
signal(SIGINT, sig_proccess);/*挂接SIGINT信号,处理函数为sig_process()*/
signal(SIGPIPE, sig_proccess);/*挂接SIGPIPE信号,处理函数为sig_pipe()*/
ss = socket(AF_INET, SOCK_STREAM, 0); /*建立一个流式套接字*/
if(ss < 0){ /*出错*/
printf("socket errorn");
return -1;
}
/*设置服务器地址*/
bzero(&server_addr, sizeof(server_addr)); /*清零*/
server_addr.sin_family = AF_INET; /*协议族*/
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);/*本地地址*/
server_addr.sin_port = htons(PORT); /*服务器端口*/
/*绑定地址结构到套接字描述符*/
err = bind(ss, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(err < 0){ /*绑定出错*/
printf("bind errorn");
return -1;
}
err = listen(ss, BACKLOG); /*设置侦听队列长度*/
if(err < 0){ /*出错*/
printf("listen errorn");
return -1;
}
/*主循环过程*/
for(;;) {
int addrlen = sizeof(struct sockaddr);
/*接收客户端连接*/
sc = accept(ss, (struct sockaddr*)&client_addr, &addrlen);
if(sc < 0){ /*客户端连接出错*/
continue; /*结束本次循环*/
}
/*建立一个新的进程处理到来的连接*/
pid = fork(); /*分叉进程*/
if( pid == 0 ){ /*子进程中*/
close(ss); /*在子进程中关闭服务器的侦听*/
process_conn_server(sc); /*处理连接*/
}else{
close(sc); /*在父进程中关闭客户端的连接*/
}
}
}
*******************处理函数***********************
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/*服务器对客户端的处理*/
void process_conn_server(int s)
{
ssize_t size = 0;
char buffer[1024]; /*数据的缓冲区*/
for(;;){ /*循环处理过程*/
size = recv(s, buffer, 1024,0);
/*从套接字中读取数据放到缓冲区buffer中*/
if(size == 0){ /*没有数据*/
return;
}
write(1,buffer,size); /*写到标准输出*/
printf("n");
//sprintf(buffer, "%d bytes altogethern", size);/*构建响应字符,为接收到客户端字节的数量*/
sprintf(buffer,"%s this is server returnn",buffer);
send(s, buffer, strlen(buffer)+1,0); /*发给客户端*/
memset(&buffer,0,sizeof(buffer)); /*清空缓冲区*/
}
}
Windows客户端:
// TCPClient.cpp : 定义控制台应用程序的入口点。
//
// TcpClient.cpp : 客户端程序
//
#include "stdafx.h"
#include <WinSock2.h>
#include <string>
#include <stdlib.h>
#include <iostream>
using namespace std;
#pragma comment(lib,"WS2_32.Lib")
#define BUF_SIZE 64 // 缓冲区大小
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsd; // 用于初始化Windows Socket
SOCKET sHost; // 与服务器进行通信的套接字
SOCKADDR_IN servAddr; // 服务器地址
char buf[BUF_SIZE]; // 用于接受数据缓冲区
int retVal;
// 初始化Windows Socket
if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
{
printf("WSAStartup failed !n");
return 1;
}
// 创建套接字
sHost = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET == sHost)
{
printf("socket failed !n");
WSACleanup();
return -1;
}
// 设置服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr("192.168.19.88"); // 用户需要根据实际情况修改
servAddr.sin_port = htons(8888); // 在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中
int sServerAddlen = sizeof(servAddr);
// 循环连接服务器
while(true)
{
retVal = connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr));
if(INVALID_SOCKET == sHost)
{
int err = WSAGetLastError();
if(err == WSAEWOULDBLOCK) // 无法立即完成非阻塞套接字上的操作
{
Sleep(500);
printf("continue !n");
continue;
}
else
{
printf("accept failed !n");
closesocket(sHost);
WSACleanup();
return -1;
}
}
printf("accept OK!n");
Sleep(500);
break;
}
// 循环向服务器发送字符串,并显示反馈信息。
// 发送quit将使服务器程序退出,同时客户端程序自身也将退出
while(true)
{
// 向服务器发送数据
printf("Please input a string to send: ");
// 接收输入的数据
std::string str;
std::getline(std::cin, str);
// 将用户输入的数据复制到buf中
ZeroMemory(buf,BUF_SIZE);
strcpy_s(buf,str.c_str());
// 向服务器发送数据
retVal = send(sHost,buf,strlen(buf),0);
//清空缓冲区
memset(&buf,0,sizeof(buf));
if(SOCKET_ERROR == retVal)
{
printf("send failed !n");
closesocket(sHost);
WSACleanup();
return -1;
}
// 接收服务器回传的数据
retVal = recv(sHost,buf,sizeof(buf)+1,0);
printf_s("Recv From Server: %sn",buf);
// 如果收到quit,则退出
//if(strcmp(buf, "quit") == 0)
//{
//printf("quit!n");
//break;
//}
}
// 释放资源
closesocket(sHost);
WSACleanup();
// 暂停,按任意键继续
system("pause");
return 0;
}
最后
以上就是纯真小蚂蚁为你收集整理的TCP实现Linux与Windows之间数据传输的全部内容,希望文章能够帮你解决TCP实现Linux与Windows之间数据传输所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复