项目目的
实现C#客户端向Java服务端发送消息以及文件的功能
设计思路
使用Socket通讯,客户端采用C#开发界面,服务端使用Java开发,最终实现向服务端发送文件和消息的功能。
服务端设计
项目结构
业务代码 SocketServer.Java
package com.taowd.socketserver;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
/**
*
* @author Taowd
* TODO Socket通讯服务端
* 2017年9月2日 下午12:04:37
*/
public class SocketServer {
/**
* 接收文件存储路径
*/
private static String path;
/**
* 端口号,可在配置文件中配置
*/
private static int port;
static {
System.out.print("读取配置文件...");
// 资源绑定
ResourceBundle rb = ResourceBundle.getBundle("config", Locale.getDefault());
path = rb.getString("path");
String portStr = rb.getString("port");
if (path == null || path.trim().equals("")) {
path = "E:/";
} else if (!path.endsWith("/")) {
path = path + "/";
}
if (portStr != null || !portStr.trim().equals("")) {
try {
port = Integer.parseInt(portStr);
} catch (Exception ex) {
System.out.println("端口获取失败,已变更为默认端口60000");
port = 60000;
}
} else {
System.out.println("未配置端口,已变更为默认端口60000");
port = 60000;
}
System.out.println("读取完成:" + "接收端口" + port + ",接收路径" + path);
}
public static void main(String[] args) {
new SocketServer().receiveFile();
}
/**
*
* @author Taowd
* TODO 接收文件操作
* 2017年9月2日 下午12:04:57
*/
@SuppressWarnings("resource")
public void receiveFile() {
ServerSocket ss = null;
Socket s = null;
BufferedInputStream in = null;
FileOutputStream out = null;
try {
ss = new ServerSocket(port);
System.out.println("服务已正常启动!");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("服务启动失败!");
}
// 永不停歇地运行
while (true) {
// 注意:此处需要和客户端保持一致
byte[] buffer = new byte[1024];
String fileName = null;
try {
s = ss.accept();
in = new BufferedInputStream(s.getInputStream());
// 取得文件名
in.read(buffer, 0, buffer.length);
fileName = new String(buffer).trim();
// 若为测试信息
if (fileName.equals("test message")) {
System.out.println("接收到测试消息!");
continue;
}
// 定义文件流
out = new FileOutputStream(
new File(path + new SimpleDateFormat("yyyymmddhhmmss").format(new Date()) + fileName));
out.flush();
buffer = new byte[1024];
// 写文件内容
int count = 0;
while ((count = in.read(buffer, 0, buffer.length)) > 0) {
out.write(buffer, 0, count);
out.flush();
buffer = new byte[1024];
}
System.out.println("接收到文件" + fileName);
} catch (Exception ex) {
System.out.println("传输异常");
ex.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (s != null) {
s.close();
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("接收文件" + fileName + "失败" + ex);
}
}
}
}
}
配置文件 config.properties
path=F://
port=60000
C#客户端设计
项目结构
工具类(FileUtils.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Windows;
namespace Socket通讯
{
/// <summary>
/// 功能:客户端Socket传送文件工具类
/// </summary>
class FileUtils
{
/// <summary>
///IP地址
/// </summary>
public static string Ip = "127.0.0.1";
/// <summary>
/// 端口号
/// </summary>
public static int Port = 60000;
/// <summary>
/// 发送文件
/// </summary>
/// <param name="path">文件全路径</param>
/// <param name="fileName">文件名</param>
/// <returns>返回执行结果0成功,-1文件不存在,-2连接失败,-3IO异常,-4未知异常</returns>
public static int StartSend(String path, String fileName)
{
if (!File.Exists(path))
{
return -1;
}
NetworkStream stream = null;
BinaryWriter sw = null;
FileStream fsMyfile = null;
BinaryReader brMyfile = null;
try
{
TcpClient client = new TcpClient(Ip, Port);
stream = client.GetStream();
sw = new BinaryWriter(stream);
///取得文件名字节数组
byte[] fileNameBytes = Encoding.Default.GetBytes(fileName);
byte[] fileNameBytesArray = new byte[1024];
Array.Copy(fileNameBytes, fileNameBytesArray, fileNameBytes.Length);
///写入流
sw.Write(fileNameBytesArray, 0, fileNameBytesArray.Length);
sw.Flush();
///获取文件内容字节数组
///byte[] fileBytes = returnbyte(filePath);
fsMyfile = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
brMyfile = new BinaryReader(fsMyfile);
///写入流
byte[] buffer = new byte[1024];
int count = 0;
while ((count = brMyfile.Read(buffer, 0, 1024)) > 0)
{
sw.Write(buffer, 0, count);
sw.Flush();
buffer = new byte[1024];
}
}
catch (SocketException se)
{
Console.WriteLine(se.StackTrace);
return -2;
}
catch (IOException ioe)
{
Console.WriteLine(ioe.StackTrace);
return -3;
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
return -4;
}
finally
{
if (sw != null)
{
sw.Close();
}
if (brMyfile != null)
{
brMyfile.Close();
}
if (fsMyfile != null)
{
fsMyfile.Close();
}
if (stream != null)
{
stream.Close();
}
}
return 0;
}
/// <summary>
/// 测试通讯
/// </summary>
/// <param name="name">测试内容需和服务端校验内容保持一致</param>
/// <returns></returns>
public static bool TestConnection(string name)
{
NetworkStream stream = null;
BinaryWriter sw = null;
try
{
TcpClient client = new TcpClient(Ip, Port);
stream = client.GetStream();
sw = new BinaryWriter(stream);
byte[] fileNameBytes = Encoding.Default.GetBytes(name);
sw.Write(fileNameBytes, 0, fileNameBytes.Length);
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
}
}
设计代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using Microsoft.Win32;
using System.IO;
namespace Socket通讯
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
txt_ip.Text = "127.0.0.1";
txt_port.Text = "60000";
}
/// <summary>
/// 单纯测试字符串传输
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, RoutedEventArgs e)
{
}
private void btn_Send_Click(object sender, RoutedEventArgs e)
{
// MessageBox.Show(txt_sendInfo.Text.Substring(txt_sendInfo.Text.LastIndexOf('\\') + 1));
if (string.IsNullOrEmpty(txt_sendInfo.Text.Trim()))
{
MessageBox.Show("文件路径不能为空!");
return;
}
//设置IP和端口号
FileUtils.Ip = txt_ip.Text.Trim();
int port = 60000;
if (Int32.TryParse(txt_port.Text.Trim(), out port))
{
FileUtils.Port = port;
}
else
{
MessageBox.Show("端口号格式不正确,请检查!");
return;
}
//注意此处的测试内容需和服务端保持一致 否则无法判断是否成功
if (FileUtils.TestConnection("test message"))
{
int result = FileUtils.StartSend(txt_sendInfo.Text, "Socket" + txt_sendInfo.Text.Substring(txt_sendInfo.Text.LastIndexOf('\\') + 1));
if (result == 0)
{
MessageBox.Show("文件发送成功!");
}
else if (result == -1)
{
MessageBox.Show("文件不存在!");
}
else if (result == -2)
{
MessageBox.Show("连接失败!");
}
else if (result == -3)
{
MessageBox.Show("IO异常!");
}
else if (result == -4)
{
MessageBox.Show("未知异常!");
}
}
else
{
MessageBox.Show("无法连接服务器!");
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
//设置IP和端口号
FileUtils.Ip = txt_ip.Text.Trim();
int port = 60000;
if (Int32.TryParse(txt_port.Text.Trim(), out port))
{
FileUtils.Port = port;
}
else
{
MessageBox.Show("端口号格式不正确,请检查!");
return;
}
if (FileUtils.TestConnection("test message"))
{
MessageBox.Show("通讯测试成功 ");
}
else
{
MessageBox.Show("通讯测试失败");
}
}
private void 选择文件_Click(object sender, RoutedEventArgs e)
{
string path = string.Empty;
OpenFileDialog dialog = new OpenFileDialog();
dialog.Title = "选择发送文件";
dialog.FileName = string.Empty;
bool? nullable = dialog.ShowDialog();
if (nullable.GetValueOrDefault() && ((bool)nullable.HasValue))
{
path = dialog.FileName;
}
txt_sendInfo.Text = path;
}
}
}
运行结果
服务端
客户端