`
haoningabc
  • 浏览: 1442852 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

tcp/ip sockets 编程 java和c的对比

阅读更多
java的socket相对容易
server端:
1.建立ServerSocket(port);
2.获取客户端socket:Socket socket = server.accept();
3.读数据:Reader reader = new InputStreamReader(socket.getInputStream());//3
4.写数据:Writer writer = new OutputStreamWriter(socket.getOutputStream());//4
client端:
1.建立socket:Socket client = new Socket(host, port);//1
2.写数据:Writer writer = new OutputStreamWriter(client.getOutputStream());//2
3.读数据:Reader reader = new InputStreamReader(client.getInputStream());//3

而c的socket为:
server端:
1.建立socket:s=socket(AF_INET,SOCK_STREAM,0))
2.bind地址:bind(s,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))
3.监听:listen(s,5);
4.获取客户端socket:cli=accept(s,(struct sockaddr *)&remote_addr,&sin_size))
5.向客户端写:len=send(cli,"welcome to my server\n",21,0);
6.从客户端读:len=recv(cli,buf,13,0);
client端:
1.建立socket:s=socket(AF_INET,SOCK_STREAM,0)),
2.链接server:connect(s,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))
3.从server读:len=recv(s,buf,BUFSIZ,0);
4.向server写len=send(s,"test3 message",13,0);



书的代码在
http://cs.ecs.baylor.edu/~donahoo/practical/CSockets2/

例子远吗在https://github.com/killinux/mysocket
参考
http://bbs.csdn.net/topics/340199431
http://haohaoxuexi.iteye.com/blog/1979837

先写段c的
client:
[root@VM_192_107_centos ipv4]# cat TCPEchoClient4.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Practical.h"
int main(int argc, char *argv[]) {
    if (argc < 3 || argc > 4) // Test for correct number of arguments
        DieWithUserMessage("Parameter(s)",
                "<Server Address> <Echo Word> [<Server Port>]");
    char *servIP = argv[1];     // First arg: server IP address (dotted quad)
    char *echoString = argv[2]; // Second arg: string to echo
    // Third arg (optional): server port (numeric).  7 is well-known echo port
    in_port_t servPort = (argc == 4) ? atoi(argv[3]) : 7;
    // Create a reliable, stream socket using TCP
    int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock < 0)
        DieWithSystemMessage("socket() failed");
    // Construct the server address structure
    struct sockaddr_in servAddr;            // Server address
    memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure
    servAddr.sin_family = AF_INET;          // IPv4 address family
    // Convert address
    int rtnVal = inet_pton(AF_INET, servIP, &servAddr.sin_addr.s_addr);
    if (rtnVal == 0)
        DieWithUserMessage("inet_pton() failed", "invalid address string");
    else if (rtnVal < 0)
        DieWithSystemMessage("inet_pton() failed");
    servAddr.sin_port = htons(servPort);    // Server port
    // Establish the connection to the echo server
    if (connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
        DieWithSystemMessage("connect() failed");
    size_t echoStringLen = strlen(echoString); // Determine input length
    // Send the string to the server
    ssize_t numBytes = send(sock, echoString, echoStringLen, 0);
    if (numBytes < 0)
        DieWithSystemMessage("send() failed");
    else if (numBytes != echoStringLen)
        DieWithUserMessage("send()", "sent unexpected number of bytes");
    // Receive the same string back from the server
    unsigned int totalBytesRcvd = 0; // Count of total bytes received
    fputs("Received: ", stdout);     // Setup to print the echoed string
    while (totalBytesRcvd < echoStringLen) {
        char buffer[BUFSIZE]; // I/O buffer
        /* Receive up to the buffer size (minus 1 to leave space for
           a null terminator) bytes from the sender */
        numBytes = recv(sock, buffer, BUFSIZE - 1, 0);
        if (numBytes < 0)
            DieWithSystemMessage("recv() failed");
        else if (numBytes == 0)
            DieWithUserMessage("recv()", "connection closed prematurely");
        totalBytesRcvd += numBytes; // Keep tally of total bytes
        buffer[numBytes] = '\0';    // Terminate the string!
        fputs(buffer, stdout);      // Print the echo buffer
    }
    fputc('\n', stdout); // Print a final linefeed
    close(sock);
    exit(0);
}

server:
[root@VM_192_107_centos ipv4]# cat TCPEchoServer4.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Practical.h"
static const int MAXPENDING = 5; // Maximum outstanding connection requests
int main(int argc, char *argv[]) {
    if (argc != 2) // Test for correct number of arguments
        DieWithUserMessage("Parameter(s)", "<Server Port>");
    in_port_t servPort = atoi(argv[1]); // First arg:  local port
    // Create socket for incoming connections
    int servSock; // Socket descriptor for server
    if ((servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        DieWithSystemMessage("socket() failed");
    // Construct local address structure
    struct sockaddr_in servAddr;                  // Local address
    memset(&servAddr, 0, sizeof(servAddr));       // Zero out structure
    servAddr.sin_family = AF_INET;                // IPv4 address family
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
    servAddr.sin_port = htons(servPort);          // Local port
    // Bind to the local address
    if (bind(servSock, (struct sockaddr*) &servAddr, sizeof(servAddr)) < 0)
        DieWithSystemMessage("bind() failed");
    // Mark the socket so it will listen for incoming connections
    if (listen(servSock, MAXPENDING) < 0)
        DieWithSystemMessage("listen() failed");
    for (;;) { // Run forever
        struct sockaddr_in clntAddr; // Client address
        // Set length of client address structure (in-out parameter)
        socklen_t clntAddrLen = sizeof(clntAddr);
        // Wait for a client to connect
        int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
        if (clntSock < 0)
            DieWithSystemMessage("accept() failed");
        // clntSock is connected to a client!
        char clntName[INET_ADDRSTRLEN]; // String to contain client address
        if (inet_ntop(AF_INET, &clntAddr.sin_addr.s_addr, clntName,
                    sizeof(clntName)) != NULL)
            printf("Handling client %s/%d\n", clntName, ntohs(clntAddr.sin_port));
        else
            puts("Unable to get client address");
        HandleTCPClient(clntSock);
    }
    // NOT REACHED
}

运行用
gcc -g -std=gnu99 TCPEchoServer4.c ../socket/DieWithMessage.c ../socket/TCPServerUtility.c ../socket/AddressUtility.c -o TCPEchoServer4
gcc -g TCPEchoClient4.c ../socket/DieWithMessage.c -o TCPEchoClient4

其中HandleTCPClient 为
void HandleTCPClient(int clntSocket) {
    char buffer[BUFSIZE]; // Buffer for echo string
    // Receive message from client
    ssize_t numBytesRcvd = recv(clntSocket, buffer, BUFSIZE, 0);
    if (numBytesRcvd < 0)
        DieWithSystemMessage("recv() failed");
    // Send received string and receive again until end of stream
    ssize_t numBytesSent_begin = send(clntSocket, "this server:",13 , 0);
    while (numBytesRcvd > 0) { // 0 indicates end of stream
        // Echo message back to client
        ssize_t numBytesSent = send(clntSocket, buffer, numBytesRcvd, 0);
        if (numBytesSent < 0)
            DieWithSystemMessage("send() failed");
        else if (numBytesSent != numBytesRcvd)
            DieWithUserMessage("send()", "sent unexpected number of bytes");

        // See if there is more data to receive
        numBytesRcvd = recv(clntSocket, buffer, BUFSIZE, 0);
        if (numBytesRcvd < 0)
            DieWithSystemMessage("recv() failed");
    }

    close(clntSocket); // Close client socket
}

----------------------------------------------------
再写一段java的 server
package com.hao;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

public class Server {

	public static void main(String args[]) throws IOException {
		int port = 8080;
		ServerSocket server = new ServerSocket(port);
		while (true) {
			Socket socket = server.accept();
			Reader reader = new InputStreamReader(socket.getInputStream());
			SocketAddress sa = socket.getRemoteSocketAddress();
			System.out.println(sa.toString());
			char chars[] = new char[64];
			int len;
			StringBuilder sb = new StringBuilder();
			String temp;
			int index;
			while ((len = reader.read(chars)) != -1) {
				temp = new String(chars, 0, len);
				if ((index = temp.indexOf("eof")) != -1) {
					sb.append(temp.substring(0, index));
					break;
				}
				sb.append(temp);
			}
			System.out.println("from client: " + sb);
			Writer writer = new OutputStreamWriter(socket.getOutputStream());
			writer.write("Hello Client.");
			writer.flush();
			writer.close();
			reader.close();
			socket.close();
		}
	}
}


client:

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;

public class Client {
	public static void main(String args[]) throws Exception {
		String host = "127.0.0.1";//"182.254.155.153";
		int port = 8080;
		Socket client = new Socket(host, port);
		Writer writer = new OutputStreamWriter(client.getOutputStream());
		writer.write("Hello Server hah.");
		writer.write("eof");
		writer.flush();
		Reader reader = new InputStreamReader(client.getInputStream());
		char chars[] = new char[64];
		int len;
		StringBuffer sb = new StringBuffer();
		String temp;
		int index;
		while ((len = reader.read(chars)) != -1) {
			temp = new String(chars, 0, len);
			if ((index = temp.indexOf("eof")) != -1) {
				sb.append(temp.substring(0, index));
				break;
			}
			sb.append(new String(chars, 0, len));
		}
		System.out.println("from server: " + sb);
		writer.close();
		reader.close();
		client.close();
	}
}


----------------------------------------------
再来一个长连接的:
package com.hao.changlianjie;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;

public class KeepAlive implements Serializable{
	 
    private static final long serialVersionUID = -2813120366138988480L;
 
    @Override
    public String toString() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"\t维持连接包";
    }
 
}



client
package com.hao.changlianjie;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ConcurrentHashMap;

public class Client {

    /**
     * 处理服务端发回的对象,可实现该接口。
     */
    public static interface ObjectAction{
        void doAction(Object obj,Client client);
    }
    public static final class DefaultObjectAction implements ObjectAction{
        public void doAction(Object obj,Client client) {
            System.out.println("处理:\t"+obj.toString());
        }
    }
    public static void main(String[] args) throws UnknownHostException, IOException {
        String serverIp = "127.0.0.1";
        int port = 65432;
        Client client = new Client(serverIp,port);
        client.start();
    }
     
    private String serverIp;
    private int port;
    private Socket socket;
    private boolean running=false;
    private long lastSendTime;
    private ConcurrentHashMap<Class, ObjectAction> actionMapping = new ConcurrentHashMap<Class,ObjectAction>();
     
    public Client(String serverIp, int port) {
        this.serverIp=serverIp;this.port=port;
    }
     
    public void start() throws UnknownHostException, IOException {
        if(running)return;
        socket = new Socket(serverIp,port);
        System.out.println("本地端口:"+socket.getLocalPort());
        lastSendTime=System.currentTimeMillis();
        running=true;
        new Thread(new KeepAliveWatchDog()).start();
        new Thread(new ReceiveWatchDog()).start();
    }
     
    public void stop(){
        if(running)running=false;
    }
     
    /**
     * 添加接收对象的处理对象。
     * @param cls 待处理的对象,其所属的类。
     * @param action 处理过程对象。
     */
    public void addActionMap(Class<Object> cls,ObjectAction action){
        actionMapping.put(cls, action);
    }
 
    public void sendObject(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        oos.writeObject(obj);
        System.out.println("发送:\t"+obj);
        oos.flush();
    }
     
    class KeepAliveWatchDog implements Runnable{
        long checkDelay = 10;
        long keepAliveDelay = 2000;
        public void run() {
            while(running){
                if(System.currentTimeMillis()-lastSendTime>keepAliveDelay){
                    try {
                        Client.this.sendObject(new KeepAlive());
                    } catch (IOException e) {
                        e.printStackTrace();
                        Client.this.stop();
                    }
                    lastSendTime = System.currentTimeMillis();
                }else{
                    try {
                        Thread.sleep(checkDelay);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Client.this.stop();
                    }
                }
            }
        }
    }
     
    class ReceiveWatchDog implements Runnable{
        public void run() {
            while(running){
                try {
                    InputStream in = socket.getInputStream();
                    if(in.available()>0){
                        ObjectInputStream ois = new ObjectInputStream(in);
                        Object obj = ois.readObject();
                        System.out.println("接收:\t"+obj);
                        ObjectAction oa = actionMapping.get(obj.getClass());
                        oa = oa==null?new DefaultObjectAction():oa;
                        oa.doAction(obj, Client.this);
                    }else{
                        Thread.sleep(10);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Client.this.stop();
                } 
            }
        }
    }
}



server:
package com.hao.changlianjie;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;

public class Server {
	/**
     * 要处理客户端发来的对象,并返回一个对象,可实现该接口。
     */
    public interface ObjectAction{
        Object doAction(Object rev);
    }
     
    public static final class DefaultObjectAction implements ObjectAction{
        public Object doAction(Object rev) {
            System.out.println("处理并返回:"+rev);
            return rev;
        }
    }
     
    public static void main(String[] args) {
        int port = 65432;
        Server server = new Server(port);
        server.start();
    }
     
    private int port;
    private volatile boolean running=false;
    private long receiveTimeDelay=3000;
    private ConcurrentHashMap<Class, ObjectAction> actionMapping = new ConcurrentHashMap<Class,ObjectAction>();
    private Thread connWatchDog;
     
    public Server(int port) {
        this.port = port;
    }
 
    public void start(){
        if(running)return;
        running=true;
        connWatchDog = new Thread(new ConnWatchDog());
        connWatchDog.start();
    }
     
    @SuppressWarnings("deprecation")
    public void stop(){
        if(running)running=false;
        if(connWatchDog!=null)connWatchDog.stop();
    }
     
    public void addActionMap(Class<Object> cls,ObjectAction action){
        actionMapping.put(cls, action);
    }
     
    class ConnWatchDog implements Runnable{
        public void run(){
            try {
                ServerSocket ss = new ServerSocket(port,5);
                while(running){
                    Socket s = ss.accept();
                    new Thread(new SocketAction(s)).start();
                }
            } catch (IOException e) {
                e.printStackTrace();
                Server.this.stop();
            }
             
        }
    }
     
    class SocketAction implements Runnable{
        Socket s;
        boolean run=true;
        long lastReceiveTime = System.currentTimeMillis();
        public SocketAction(Socket s) {
            this.s = s;
        }
        public void run() {
            while(running && run){
                if(System.currentTimeMillis()-lastReceiveTime>receiveTimeDelay){
                    overThis();
                }else{
                    try {
                        InputStream in = s.getInputStream();
                        if(in.available()>0){
                            ObjectInputStream ois = new ObjectInputStream(in);
                            Object obj = ois.readObject();
                            lastReceiveTime = System.currentTimeMillis();
                            System.out.println("接收:\t"+obj);
                            ObjectAction oa = actionMapping.get(obj.getClass());
                            oa = oa==null?new DefaultObjectAction():oa;
                            Object out = oa.doAction(obj);
                            if(out!=null){
                                ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
                                oos.writeObject(out);
                                oos.flush();
                            }
                        }else{
                            Thread.sleep(10);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        overThis();
                    } 
                }
            }
        }
         
        private void overThis() {
            if(run)run=false;
            if(s!=null){
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("关闭:"+s.getRemoteSocketAddress());
        }
         
    }
     
}

分享到:
评论

相关推荐

    TCP/IP Socket in C/Java

    两本TCP/IP socket编程书,分别是C语言和Java语言版的。都是文字版的pdf文档。 1. TCP/IP Sockets in Java (2th Edtion) 2. TCP/IP Sockets in C *Series Editor: Michael J. Donahoo

    TCP_IP_Sockets_in_Java

    TCP_IP_Sockets_in_Java,有代码

    TCP.IP.Sockets.in.Java.2nd.Edition.pdf (TCP/IP Socket 编程)

    TCP/IP Socket 编程 英文原版,必看中文的扫描版舒服多了,很清晰

    TCPIP.Sockets.in.Java.Practical.Guide.for.Programmers.2nd.Edition

    一本讲Java TCPIP编程的书,比较新。

    第13章-Java网络编程-Java面向对象程序设计教程-微课视频版-程杰-清华大学出版社.pptx

    13.1 TCP/IP协议简介 13.2 网络开发中的常用工具类 13.3 面向连接的TCP通信 13.4 无连接的UDP通信 13.5 UDP广播通信 13.6 局域网通信工具 第13章 Java网络编程 第13章-Java网络编程-Java面向对象程序设计教程-微课...

    Socket TCP Java 高清学习资料合集

    包括 1.TCP-IP详解卷1:协议 中文版PDF...2.高级TCP/IP编程 中文版PDF 3.TCPIP Sockets in Java 2nd 英文版PDF, 4.Advanced JAVA networking英文版PDF 5.中文版Socket Java教程 6.Socket Java学习笔记 7.UDP简单案例

    使用socket和DTU通信.doc

    为了方便网络编程,90年代初,由microsoft联合了其他几家公司共同制定了一套windows下的网络编程接口,即windows sockets规范,它不是一种网络协议,而是一套开放的、支持多种协议的windows下的网络编程接口。...

    Java_TCPIP_Socket编程(中文版&英文版)

    2.2 TCP Sockets 15 2.2.1 TCP Client 16 2.2.2 TCP Server 21 2.2.3 Input and Output Streams 25 2.3 UDP Sockets 26 2.3.1 DatagramPacket 27 2.3.2 UDP Client 29 2.3.3 UDP Server 34 2.3.4 Sending and ...

    SOCKET聊天系统分析设计

    针对当前中小型企业办公人员对即时通讯软件要求较低等问题, 提出了一种基于Java平台下的网络聊天系统的设计与实现方案,对系统进行了整体设计和详细设计,该系统主要通过Java Socket网络编程实现通信,具有速度快,高...

    本科生计算机专业毕业论文(设计)开题报告

    文件传输系统主要功能是自动获取局域网内用户的主机名,IP地址以及工作组名字,最终以C/S模式通过TCP/IP协议实现点到点文件传输功能。本系统既锻炼了我们的实际动手能力,使我们将大学四年所学的理论知识与实际开发...

    java tcpip 编程

    Morgan.Kaufmann.TCP.IP.Sockets.in.Java.2nd.Edition.Feb.2008

    基于java的局域网聊天系统-毕业设计.doc

    图1 Socket 的编程模型 字节流套接字(Stream Socket) 是最常用的套接字类型,TCP/IP协议族中的 TCP 协议使用此类接口。字节流套接口提供面向连接的、无差错的、发送先后顺序一致的、 无记录边界和非重复的网络信息...

    Java Network Programming 3rd Edition By Elliotte Rusty Harold 2004

    IP, TCP, and UDP Section 2.4. The Internet Section 2.5. The Client/Server Model Section 2.6. Internet Standards Chapter 3. Basic Web Concepts Section 3.1. URIs Section 3.2. HTML, SGML, ...

    C# socket 源码 多人聊天

     套接字是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。可以将套接字看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面。套接字存在于通信域中,通信域是为了处理一般...

Global site tag (gtag.js) - Google Analytics