TCP实现Linux与Windows之间数据传输
实验要求:用两台计算机,一台是服务器另一台是客户端,运行结果要求在客户端把键入的字符串发送给服务器,服务器显示收到的字符串,并将字符串发回给客户端,客户端显示服务器发回的字符串。要求客户端能够多次发送字符串,服务器能够不断的接收并显示和发送。Linux服务器:#include#include#include#include#include#include
实验要求:用两台计算机,一台是服务器另一台是客户端,运行结果要求在客户端把键入的字符串发送给服务器,服务器显示收到的字符串,并将字符串发回给客户端,客户端显示服务器发回的字符串。要求客户端能够多次发送字符串,服务器能够不断的接收并显示和发送。
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 error\n");
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 error\n");
return -1;  
} 
err = listen(ss, BACKLOG); /*设置侦听队列长度*/
if(err < 0){  /*出错*/
printf("listen error\n");
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 altogether\n", size);/*构建响应字符,为接收到客户端字节的数量*/
sprintf(buffer,"%s this is server return\n",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: %s\n",buf); 
  // 如果收到quit,则退出
  //if(strcmp(buf, "quit") == 0)
  //{
  //printf("quit!\n");
  //break;
  //}
  }
  // 释放资源 
  closesocket(sHost); 
  WSACleanup(); 
  // 暂停,按任意键继续
  system("pause");
  return 0; 
  }
更多推荐
 
 



所有评论(0)